Re-scaling a rectangle based on the rotation of it’s content

As you might have noticed in the video in my earlier post, the bounding box of the sprite is scaling based on the rotation. This is useful as it ensures that even if the content is rotated, it is always within the bounds of the rectangle. To illustrate this, take a look at the following photos:

A 6 by 6 square without rotation

 

The same 6 by 6 square, but now rotated by 45 degrees

When we rotate the blue square, its bounds increases to the square in green. This is what we are trying to compensate for. The following formula gives us the delta x and y from the origin point.

func

The formula that gives us delta x and y

Using this formula, we find that dx’ = 4.24 and dy’ = 4.24. Please note that this formula will work for any sizes, I’m just using a square for simplicity. By applying this to code, we get the following in C#:

public Rectangle getBoundsWithRotation(Rectangle rect, float angle)
{
    Vector2 origin = new Vector2((float)rect.X + rect.Width / 2.0f, 
        (float)rect.Y + rect.Height / 2.0f);

    float dx = (float)Math.Abs(Math.Cos(angle)) * (rect.Width / 2.0f) + 
        (float)Math.Abs(Math.Sin(angle)) * (rect.Height / 2.0f);
    float dy = (float)Math.Abs(Math.Sin(angle)) * (rect.Width / 2.0f) + 
        (float)Math.Abs(Math.Cos(angle)) * (rect.Height / 2.0f);

    int x = (int)Math.Round(origin.X - dx);
    int y = (int)Math.Round(origin.Y - dy);
    int w = (int)Math.Round(dx * 2.0f);
    int h = (int)Math.Round(dy * 2.0f);

    return new Rectangle(x, y, w, h);
}

2 Comments

  • Marcus Specht says:

    Hey Håvard ,
    nice one… thx. But why do you calculate
    float rot = angle % (float)Math.PI / 2.0f;
    without using it afterwards?

    • Nex says:

      Hi Marcus, thank you for noticing! I should actually have omitted that, as it is part of an older version of the code where the corners were calculated by using an interpolation-like expression instead. It worked, but was not very intuitive and had performed a little worse if I remember correctly. If you are interested, I can hook you up with the code. I’ll get this post cleaned up shortly. Thanks again 😉

Leave a Reply

Your email address will not be published. Required fields are marked *