Skip to content
Advertisement

How to calculate a bounding box for a rectangle rotated around its center?

I am looking to calculate the bounding box of a rectangle rotated around its center. I have read this question and while MarkusQ’s answer works in general, it is not efficient enough for my needs. I am trying to get Troubadour’s answer working, but it seems to only work when the origin of rotation is around a corner, not the center.

Is it possible to adapt his solution to work with rectangles that have their origin of rotation around their center?

I’ve developed a full recreation of the problem below:

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

function drawRectangle(rX, rY, rW, rH) {
  ctx.beginPath();
  ctx.rect(rX, rY, rW, rH);
  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(rX, rY, rW, rH, rAngle) {
  let rXCenter = rX + rW / 2;
  let rYCenter = rY + rH / 2;

  rotateCanvas(rAngle, rXCenter, rYCenter);
  drawRectangle(rX, rY, rW, rH);
  rotateCanvas(-rAngle, rXCenter, rYCenter);
}

function computeAABBCenter(x, y, w, h, theta) {
  const ux = Math.cos(theta) * 0.5; // half unit vector along w
  const uy = Math.sin(theta) * 0.5;
  const wx = w * ux;
  const wy = w * uy; // vector along w
  const hx = h * -uy;
  const hy = h * ux; // vector along h
  
  // all point from top left CW
  const x1 = x - wx - hx;
  const y1 = y - wy - hy;
  const x2 = x + wx - hx;
  const y2 = y + wy - hy;
  const x3 = x + wx + hx;
  const y3 = y + wy + hy;
  const x4 = x - wx + hx;
  const y4 = y - wy + hy;
  
  return {
    x1: Math.min(x1, x2, x3, x4),
    y1: Math.min(y1, y2, y3, y4),
    x2: Math.max(x1, x2, x3, x4),
    y2: Math.max(y1, y2, y3, y4),
  };
}

let rX = 100;
let rY = 100;
let rW = 100;
let rH = 50;
let rA = 0.707;

drawRotatedRectangle(rX, rY, rW, rH, rA);

let bb = computeAABBCenter(rX, rY, rW, rH, rA);

drawRectangle(bb.x1, bb.y1, bb.x2 - bb.x1, bb.y2 - bb.y1);
body { margin: 0; overflow: hidden; }
<canvas width="800" height="800"></canvas>

As you can see, the bounding box rectangle is not correct. Here’s what it currently looks like, and what it should look like:

enter image description here

Advertisement

Answer

Size of bounding box (description here)

H = w * Abs(Sin(Fi)) + h * Abs(Cos(Fi))
W = w * Abs(Cos(Fi)) + h * Abs(Sin(Fi))

Having rXCenter, rYCenter, you can find get bounds coordinates

x0  = rXCenter - W/2
y0  = rYCenter - H/2
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement