Question

I'm rotating a jCanvas layer about its center, but after that I need to compute its new x and y coordinates. I'm using the below code, though it returns bad values:

var rotation = layer.rotate * Math.PI / 180;

//object's middle
var middleX = layer.x + layer.width / 2;
var middleY = layer.y + layer.height / 2;

//new coords (wrong)
var newX = middleX * Math.cos(rotation) - middleY * Math.sin(rotation);
var newY = middleX * Math.sin(rotation) + middleY * Math.cos(rotation);

For simple rotations - for example by 90 degrees I can get new corner's x and y like that:

var middleX = layer.x + layer.width / 2;
var middleY = layer.y + layer.height / 2;
var newX = middleX - layer.height / 2;
var newY = middleY - layer.width / 2;

But what about more complicated cases?

EDIT:

I've found this formula, but it works properly only when I'm rotating clockwise. What about counterclockwise rotations?

var newX = (layer.x - middleX) * Math.cos(rotation) - (layer.y - middleY) * Math.sin(rotation) + middleX;
        var newY = (layer.x - middleX) * Math.sin(rotation) + (layer.y - middleY ) * Math.cos(rotation) + middleY;
Was it helpful?

Solution

You are about to rotate about the center and get the new corner coordinate. Assuming you want to get the largest bounding box with the angle is not 90 degree:

var theta = layer.rotate*Math.PI/180.;

// Find the middle rotating point
var midX = layer.x + layer.width/2;
var midY = layer.y + layer.height/2;

// Find all the corners relative to the center
var cornersX = [layer.x-midX, layer.x-midX, layer.x+layer.width-midX, layer.x+layer.width-midX];
var cornersY = [layer.y-midY, layer.y+layer.height-midY, midY-layer.y, layer.y+layer.height-midY];

// Find new the minimum corner X and Y by taking the minimum of the bounding box
var newX = 1e10;
var newY = 1e10;
for (var i=0; i<4; i=i+1) {
    newX = min(newX, cornersX[i]*Math.cos(theta) - cornersY[i]*Math.sin(theta) + midX);
    newY = min(newY, cornersX[i]*Math.sin(theta) + cornersY[i]*Math.cos(theta) + midY);
}

// new width and height
newWidth = midX - newX;
newHeight = midY - newY;

OTHER TIPS

    var theta = layer.rotate*Math.PI/180.;
    // Find the middle rotating point
    var midX = layer.x+ layer.width/2;
    var midY = layer.y+ layer.height/2;
    // Find all the corners relative to the center
    var cornersX = [layer.x-midX, layer.x-midX, layer.x+layer.width-midX, layer.x+layer.width-midX];
    var cornersY = [layer.y-midY, layer.y+layer.height-midY, midY-layer.y, midY-(layer.y+layer.height)];
    // Find new the minimum corner X and Y by taking the minimum of the bounding box
    var newX = 1e10;
    var newY = 1e10;
    for (var i=0; i<4; i=i+1) {
        newX = cornersX[i]*Math.cos(theta) - cornersY[i]*Math.sin(theta) + midX
        newY = cornersX[i]*Math.sin(theta) + cornersY[i]*Math.cos(theta) + midY
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top