Oldrich Svec
Oldrich Svec

Reputation: 4231

Shape transformation - circular section

Is there any simple transformation (transformation matrix...) that will transform section A into section B? The only requirement is that both sections should have the same size X.

I plan to fill section A with an image and then to transform it into section B including the image. Right now I use javascript KineticJS but I am willing to change the framework if necessary.

Is that doable?

Section A transformed to section B

Upvotes: 0

Views: 91

Answers (1)

markE
markE

Reputation: 105015

Your solution is not trivial.

Consider this illustration:

Lines radiate 360 degrees outward from a centerpoint and pass through both arcs A and B.

enter image description here

This illustration shows many more lines around the centerpoint.

enter image description here

Think of this as moving every pixel from A to a corresponding pixel in B. This uses linear interpolation (lerping) to move each pixel from A to B. The total number of colored pixels in A & B are the same--no pixels have been "magically" added to B.

Here’s code for this illustration:

var cx=150;
var cy=150;

ctx.lineWidth=1;
for(var a=0;a<Math.PI*2;a+=Math.PI/240){
for(var r=25;r<50;r++){
    var x1=cx+r*Math.cos(a);
    var y1=cy+r*Math.sin(a);
    var x2=cx+(r+25)*Math.cos(a);
    var y2=cy+(r+25)*Math.sin(a);
    ctx.fillStyle="blue";
    ctx.fillRect(x1,y1,1,1);
    ctx.fillStyle="blue";
    ctx.fillRect(x2,y2,1,1);
}
}
ctx.lineWidth=2;
ctx.beginPath();
ctx.arc(cx,cy,25,0,Math.PI*2);
ctx.closePath();
ctx.stroke();
ctx.beginPath();
ctx.arc(cx,cy,50,0,Math.PI*2);
ctx.closePath();
ctx.stroke();
ctx.beginPath();
ctx.arc(cx,cy,75,0,Math.PI*2);
ctx.closePath();
ctx.stroke();

The problem

Notice that most of arc A is filled with blue pixels while some parts of B are “moired” (not completely filled). That’s because A’s quantity of pixels will not completely fill B’s larger space.

Your image would appear the same. It would appear "correctly" in arc A but would have missing pixels in arc B.

What you need to do is “fill in the gaps in B” with appropriately determined pixels.

The solution

You can do this with an algorithm like bilinear interpolation which fills in the gaps in B by selecting a “best” pixel color. It does this by comparing 4 adjacent pixels in arc A. This algorithm enlarges a smaller image into a larger image by filling in "missing" pixels inside the larger space.

You will have to slightly adjust this algorithm to do non-axis-aligned interpolation. Here’s an link to a nice example of bilinear interpolation:

http://strauss.pas.nu/js-bilinear-interpolation.html

Upvotes: 1

Related Questions