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:
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