Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

378
Views
How to rotate a rectangle around an origin?

I'm trying to rotate two rectangles the same amount around the same point. The point is arbitrary, so for simplicity, I'm using the top-left (0, 0)

Unfortunately, the result seems slightly off, and I'm not sure what's causing it. Here is a full reproduction of the issue:

let canvas = document.querySelector("canvas");
let ctx = canvas.getContext("2d");

class Rectangle {
  constructor(x, y, w, h, theta) {
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
    this.theta = theta;
  }
}

function drawRectangle(r) {
  ctx.beginPath();
  ctx.rect(r.x, r.y, r.w, r.h);
  ctx.stroke();
}

function degreesToRadians(degrees) { return degrees * (Math.PI / 180); }

function rotateCanvas(radians, centerX, centerY) {
  ctx.translate(centerX, centerY);
  ctx.rotate(radians);
  ctx.translate(-centerX, -centerY);
}

function drawRotatedRectangle(r) {
  let rXCenter = r.x + (r.w / 2);
  let rYCenter = r.y + (r.h / 2);
  alert(rXCenter);

  rotateCanvas(r.theta, rXCenter, rYCenter);
  drawRectangle(r);
  rotateCanvas(-r.theta, rXCenter, rYCenter);
}

let r1 = new Rectangle(100, 52, 90, 30, degreesToRadians(-20));
let r2 = new Rectangle(140, 80, 25, 25, degreesToRadians(10));

function simpleRotate(r, theta) {
  let transX = Math.cos(theta) * r.x - Math.sin(theta) * r.y;
  let transY = Math.sin(theta) * r.x + Math.cos(theta) * r.y;

  return new Rectangle(transX, transY, r.w, r.h, r.theta + theta);
}

drawRotatedRectangle(r1);
drawRotatedRectangle(r2);

let r1AABB = simpleRotate(r1, -r1.theta);
let r2Rotate = simpleRotate(r2, -r1.theta);

ctx.strokeStyle = "#ff0000";
drawRotatedRectangle(r1AABB);
drawRotatedRectangle(r2Rotate);
body { margin: 0; overflow: hidden; }
<canvas width="600" height="600"></canvas>

The black rectangles are the two rectangles before being rotated, and the red rectangles are the two rectangles after being rotated.

As you can see, the two black rectangles are touching (colliding) before being rotated. Then, I rotate them both by the same amount around the same point (0, 0). However, afterwards they are no longer touching (as you can see the red rectangles are no longer colliding.

Why is this? I followed this code for rotating a point, but I seem to be getting inaccurate results.

If I take a screenshot of the black rectangles, open it up an image editor, box select them, and rotate them, then they stay together (colliding). How can I emulate this in my code example posted above?

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

This may let it work as you expect.

function simpleRotate(r, theta) {
    let transX = Math.cos(theta) * (r.x + r.w / 2) - Math.sin(theta) * (r.y + r.h / 2) - r.w / 2;
    let transY = Math.sin(theta) * (r.x + r.w / 2) + Math.cos(theta) * (r.y + r.h / 2) - r.h / 2;
    return new Rectangle(transX, transY, r.w, r.h, r.theta + theta);
}

Other otherwise, if you'd like to change center, use following form.

function simpleRotate(r, theta, centerX, centerY) {
    let transX = Math.cos(theta) * (r.x + r.w / 2 - centerX) - Math.sin(theta) * (r.y + r.h / 2 - centerY) - r.w / 2 + centerX;
    let transY = Math.sin(theta) * (r.x + r.w / 2 - centerX) + Math.cos(theta) * (r.y + r.h / 2 - centerY) - r.h / 2 + centerY;
    return new Rectangle(transX, transY, r.w, r.h, r.theta + theta);
}

Then

let r1AABB = simpleRotate(r1, -r1.theta, 145, 67);
let r2Rotate = simpleRotate(r2, -r1.theta, 145, 67);

How these work

In general, 2d rotational transform with offset consists of translation and rotation. Then, in that setup rotation is to be applied via drawRotatedRectangle() afterwards. Therefore all what you have to do is to compose appropriate translation. Inspecting simpleRotate() function carefully, you'll notice what's actually done there is calculation of translation (transX, transY ... though sin/cos are being used).

Then, as you know, since drawRotatedRectangle() rotates the rectangle around its center, by composing translation to move the center to the appropriate position, you can obtain rotational transform you need.

enter image description here

Initial state → Translate each item by simpleRotate() → Rotate each item by drawRotatedRectangle() → Final state.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!