Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning un-transformed mouse coordinates after rotating an object on html5 canvas

I am rotating an object in html5 canvas around a variable point of origin.

If a user clicks on a given point in the newly rotated rectangle, I need the returned mouse coordinates to be rotated back around the same point of origin.

I have made a very quick drawing to hopefully illustrate better:

enter image description here

I essentially need a function that will take the actual clicked mouse coordinates as x and y and transform them to the objects position BEFORE it was rotated.

var origin = {
        x: 100,
        y: 100
};

var angle = 45;

function transformCoordinates(x,y){

         //Perform calculation to transform coordinates

         return {
                 x : newx,
                 y : newy
         };
}

The variables available will be the transformation origin of the rotation and the angle. As well as the mouse click coordinate on the canvas (relative to the canvas itself, with 0,0 being the top left point etc)

Unfortunately math is not my strong point. Hopefully someone can help.

like image 700
gordyr Avatar asked Jan 25 '13 11:01

gordyr


3 Answers

There is an even more elegant way to solve this problem than the way you did, but you need to know how to do matrix multiplication to understand it.

You can use context.currentTransform to get the transformation matrix of the canvas. This matrix represents all the coordinate modifications resulting from all scale- translate- and rotate modifiers currently applied to the context state. Here is the documentation of the matrix.

To convert internal coordinates to screen coordinates, use these formulas:

screen_X = internal_X * a + internal_Y * c + e;    
screen_Y = internal_X * b + internal_Y * d + f;
like image 192
Philipp Avatar answered Nov 14 '22 19:11

Philipp


Embarrassingly I solved this problem straight after asking the question.

In case anyone else needs the same sort of function, here is how I did it:

getTransformedCoords : function(coords){
    var self = this;
    var obj = self.activeObj;
    var angle = (obj.angle*-1) * Math.PI / 180;   
    var x2 = coords.x - obj.left;
    var y2 = coords.y - obj.top;
    var cos = Math.cos(angle);
    var sin = Math.sin(angle);

    var newx = x2*cos - y2*sin + obj.left; 
    var newy = x2*sin + y2*cos + obj.top;

    return {
        x : newx,
        y : newy
    };
},
like image 4
gordyr Avatar answered Nov 14 '22 18:11

gordyr


I was also searching for this kind of query for a quite a bit of time. In my case, I was experimenting in canvas to display a dot point, when user mouse-click over the canvas, even after rotation. The issue was, after context rotation the points where wrongly displayed. I took the method provided by gordyr .

I have modified the code slightly for my code base. I have put my complete code base here.

let model = {
    ctx: {},
    canvas: {},
    width: 500,
    height: 500,
    angleInRad: 0
};
function getTransformedCoords(coords) {
    var angle = (model.angleInRad * -1);
    var x2 = coords.x;
    var y2 = coords.y;
    var cos = Math.cos(angle);
    var sin = Math.sin(angle);

    var newx = Math.floor(x2 * cos - y2 * sin);
    var newy = Math.floor(x2 * sin + y2 * cos);

    return new Position(newx, newy);
}

Once again thank you gordyr for your code.

like image 2
MishkuMoss Avatar answered Nov 14 '22 17:11

MishkuMoss