Calculate Bounding box coordinates from a rotated rectangle

  • Transform the coordinates of all four corners
  • Find the smallest of all four x's as min_x
  • Find the largest of all four x's and call it max_x
  • Ditto with the y's
  • Your bounding box is (min_x,min_y), (min_x,max_y), (max_x,max_y), (max_x,min_y)

AFAIK, there isn't any royal road that will get you there much faster.

If you are wondering how to transform the coordinates, try:

x2 = x0+(x-x0)*cos(theta)+(y-y0)*sin(theta)
y2 = y0-(x-x0)*sin(theta)+(y-y0)*cos(theta)

where (x0,y0) is the center around which you are rotating. You may need to tinker with this depending on your trig functions (do they expect degrees or radians) the sense / sign of your coordinate system vs. how you are specifying angles, etc.


I realize that you're asking for ActionScript but, just in case anyone gets here looking for the iOS or OS-X answer, it is this:

+ (CGRect) boundingRectAfterRotatingRect: (CGRect) rect toAngle: (float) radians
{
    CGAffineTransform xfrm = CGAffineTransformMakeRotation(radians);
    CGRect result = CGRectApplyAffineTransform (rect, xfrm);

    return result;
}

If your OS offers to do all the hard work for you, let it! :)

Swift:

func boundingRectAfterRotatingRect(rect: CGRect, toAngle radians: CGFloat) -> CGRect {
    let xfrm = CGAffineTransformMakeRotation(radians)
    return CGRectApplyAffineTransform (rect, xfrm)
}

The method outlined by MarkusQ works perfectly but bear in mind that you don't need to transform the other three corners if you have point A already.

An alternative method, which is more efficient, is to test which quadrant your rotation angle is in and then simply compute the answer directly. This is more efficient as you only have a worst case of two if statements (checking the angle) whereas the other approach has a worst case of twelve (6 for each component when checking the other three corners to see if they are greater than the current max or less than the current min) I think.

The basic algorithm, which uses nothing more than a series of applications of Pythagoras' theorem, is shown below. I have denoted the rotation angle by theta and expressed the check there in degrees as it's pseudo-code.

ct = cos( theta );
st = sin( theta );

hct = h * ct;
wct = w * ct;
hst = h * st;
wst = w * st;

if ( theta > 0 )
{
    if ( theta < 90 degrees )
    {
        // 0 < theta < 90
        y_min = A_y;
        y_max = A_y + hct + wst;
        x_min = A_x - hst;
        x_max = A_x + wct;
    }
    else
    {
        // 90 <= theta <= 180
        y_min = A_y + hct;
        y_max = A_y + wst;
        x_min = A_x - hst + wct;
        x_max = A_x;
    }
}
else
{
    if ( theta > -90 )
    {
        // -90 < theta <= 0
        y_min = A_y + wst;
        y_max = A_y + hct;
        x_min = A_x;
        x_max = A_x + wct - hst;
    }
    else
    {
        // -180 <= theta <= -90
        y_min = A_y + wst + hct;
        y_max = A_y;
        x_min = A_x + wct;
        x_max = A_x - hst;
    }
}

This approach assumes that you have what you say you have i.e. point A and a value for theta that lies in the range [-180, 180]. I've also assumed that theta increases in the clockwise direction as that's what the rectangle that has been rotated by 30 degrees in your diagram seems to indicate you are using, I wasn't sure what the part on the right was trying to denote. If this is the wrong way around then just swap the symmetric clauses and also the sign of the st terms.