0

I am attempting to distort an image displayed within a canvas, so it looks like a "planet". However I am struggling to find away to deal with a distortion issue. The only solution coming to mind is to find a way to reduce the radiusDistance variable, the bigger it is. That said, I am unsure how to achieve this. Any suggestions?

Below is the math and objects I am currently using to achieve this:

polarArray = [];
var polar = function(a,r,c){ //polar object, similar to pixel object.
    this.a = a; //angle
    this.r = r; //radius (distance)
    this.color = c; //color, stored using an object containg r,g,b,a variables
};
loopAllPixels(function(loop){//loop through every pixel, stored in a pixel array
    var pixel = loop.pixel;
    /*each pixel object is structured like this:
        pixel {
            x,
            y,
            color {
                r,
                g,
                b,
                a
            }
        }
    */
    var angle = pixel.x/360*Math.PI;
    var radiusDistance = pixel.y/Math.PI;
    polarArray.push(new polar(angle,radiusDistance,pixel.color));//store polar coordinate pixel + colour.
    pixel.color = new colorRGBA(255,255,255,255);//set background as white.
});
for (var i=0;i<polarArray.length;i++){//loop through polarArray (polar coordinate pixels + colour)
    var p = polarArray[i]; //polar pixel
    var x = (p.r*Math.cos(p.a))+(canvas.width/2); //x coordinate
    var y = (p.r*Math.sin(p.a))+(canvas.height/2); //y coordinate
    if (setpixel(x,y,p.color)==true){ //set pixel at location.
        continue;
    }
    break;

}
updatePixelsToContext();//draw to canvas

And here is the effect it currently produces (note that I flip the image horizontally before applying it to the canvas, and in this example, I set the background with a magenta kind of colour, for better clarity of the issue):

enter image description here


Note: I am intending for the warping effect, just not the "ripping" of the pixels, caused by not obtaining all the neccessary pixel data required.

Also bear in mind that speed and effeciency isn't my priority here as of yet.

Matthew Spence
  • 986
  • 2
  • 9
  • 27
  • 3
    Rather than do each pixel in the image, scan across each pixel in the destination circle. Use the X and Y coord of the destination to locate the coordinate on the source image and then set the destination to the correct value. – Blindman67 Feb 29 '16 at 22:45
  • Hmmm.. do you know of any good algorithms for creating circles where I can store each pixel into an array, using my pixel object? (Note: using cartesian coordinates... as I don't see an achievable method for polar-coordinates).. also, by using that method, won't the final product effectively just be the source image cropped into a circle? (this is not the aim) @Blindman67 – Matthew Spence Mar 01 '16 at 14:08
  • 1
    You do not provide enough information To convert from cart to polar is just `function cart2Polar(x,y){ return {dir:Math.atan2(y,x), dist : Math.hypot(x,y) }}` but how that relates to the image x,y is unknown as you provide no information on how polarArray is populated, (that function adding to polarArray should be part of your render code) Storing an image using your polarArray is exceedingly.. no sorry, I mean ludicrously, inefficient and I am understating it. – Blindman67 Mar 01 '16 at 19:01
  • on top of all @Blindman67 wrote you should find 4 closest points in polar and bi-linearly interpolate the actual pixel color. (or 16 closest points for bi-cubic interpolation) – Spektre Mar 03 '16 at 09:11

0 Answers0