Or05230
Or05230

Reputation: 83

Calculate 2D rotation javascript HTML canvas

Implemented a canvas, Drawing a square there and get the calculated coordinates,
Can see on the following pic the drawing: canvas draw

I'm calculating and getting the upleft point X and Y coordinates,
And for the down right coordinates that i need, I'm adding the height and width, as follows:

 { upLeft: { x: position.x, y: position.y }, downRight: { x: position.x + position.width, y: position.y + position.height } },

Now i want to get the same dimensions when i'm rotating the canvas clockwise or anti-clockwise. So i have the angle, And i try to calculate via the following function:

 function getRotatedCoordinates(cx, cy, x, y, angle) {
    let radians = (Math.PI / 180) * angle,
        cos = Math.cos(radians),
        sin = Math.sin(radians),
        nx = (cos * (x - cx)) - (sin * (y - cy)) + cx,
        ny = (cos * (y - cy)) + (sin * (x - cx)) + cy;
    return [nx, ny];
  }

And i'm calling the function via the following args and using it.

let newCoords = getRotatedCoordinates(0, 0, position.x, position.y, angle);
position.x = newCoords[0];
position.y = newCoords[1];

So firstly, I'm not sure that the cx and cy points are correct, I'm always entering 0 for both of them. Secondly, I'm not getting the desired results, They are getting changed but i'm pretty sure that something is wrong with the x and y, So i guess that the function is wrong. Thanks.

Upvotes: 1

Views: 182

Answers (1)

Helder Sepulveda
Helder Sepulveda

Reputation: 17584

Here is how I would do it:

function getRectangeCoordinates(x, y, width, height, angle) {
  let points = [ [x, y] ]
  let radians = (Math.PI / 180) * angle;
  for (let i = 0; i < 3; i++) {
    x += Math.cos(radians) * ((i == 1) ? height : width);
    y += Math.sin(radians) * ((i == 1) ? height : width);
    points.push([x, y])
    radians += Math.PI / 2
  }
  return points
}

let canvas = document.createElement("canvas");
canvas.width = canvas.height = 140
let ctx = canvas.getContext('2d');
document.body.appendChild(canvas);

function draw(coords, radius) {
  for (let i = 0; i < 4; i++) {
    ctx.beginPath();
    ctx.arc(coords[i][0], coords[i][1], radius, 0, 8);
    ctx.moveTo(coords[i][0], coords[i][1]);
    let next = (i + 1) % 4
    ctx.lineTo(coords[next][0], coords[next][1]);
    ctx.stroke();
  }
}

let coords = getRectangeCoordinates(20, 10, 120, 40, 15)
console.log(JSON.stringify(coords))
draw(coords, 3)

ctx.strokeStyle = "red";
coords = getRectangeCoordinates(60, 40, 40, 50, 65)
draw(coords, 5)

ctx.strokeStyle = "blue";
coords = getRectangeCoordinates(120, 3, 20, 20, 45)
draw(coords, 2)

In the getRectangeCoordinates I'm returning all corners of a rectangle and the paraments of the function are the top left corner (x, y) the height and width of the rectangle and last the angle.

I'm drawing a few rectangles with different shapes and angles to show how it looks like


The calculations in the function are simple trigonometry here is a visual representation that could help you remember it the next time you need it:

Upvotes: 2

Related Questions