0
votes

I know Rectangle is axis aligned, that's fine, I just can't figure out how to create a rectangle so it is always encompassing the entire sprite, regardless of rotation. I have been looking everywhere for an answer but I can't get a straight one anywhere.

For example:

enter image description here

enter image description here

Assuming the origin point is the middle of the texture, how can I go about this?

EDIT

Fiddling around with it a little, I've gotten this far:

public Rectangle BoundingBox
{
    get
    {

        var cos = Math.Cos(SpriteAngle);
        var sin = Math.Cos(SpriteAngle);

        var t1_opp = Width * cos;
        var t1_adj = Math.Sqrt(Math.Pow(Width, 2) - Math.Pow(t1_opp, 2));

        var t2_opp = Height * sin;
        var t2_adj = Math.Sqrt(Math.Pow(Height, 2) - Math.Pow(t2_opp, 2));

        int w = Math.Abs((int)(t1_opp + t2_opp));
        int h = Math.Abs((int)(t1_adj + t2_adj));

        int x = Math.Abs((int)(Position.X) - (w / 2));
        int y = Math.Abs((int)(Position.Y) - (h / 2));

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

    }
}

enter image description here

2

2 Answers

0
votes

(doing this off the top of my head.. but the principle should work)

Create a matrix to rotate around the center of the rectangle - that is a translate of -(x+width/2), -(y+height/2) followed by a rotation of angle followed by a translate of (x+width/2), (y+height/2)

Use Vector2.Transform to transform each corner of the original rectangle

Then make a new rectangle with x = min(p1.x, p2.x, p3.x, p4.x) width = max(p1.x, p2.x, p3.x, p4.x) - x

similar for y

0
votes

Sorry this is coming so late, but I figured this out a while ago and forgot to post an answer.

public virtual Rectangle BoundingBox
{
    get
    {
        int x, y, w, h;
        if (Angle != 0)
        {
            var cos = Math.Abs(Math.Cos(Angle));
            var sin = Math.Abs(Math.Sin(Angle));
            var t1_opp = Width * cos;
            var t1_adj = Math.Sqrt(Math.Pow(Width, 2) - Math.Pow(t1_opp, 2));
            var t2_opp = Height * sin;
            var t2_adj = Math.Sqrt(Math.Pow(Height, 2) - Math.Pow(t2_opp, 2));

            w = (int)(t1_opp + t2_opp);
            h = (int)(t1_adj + t2_adj);
            x = (int)(Position.X - (w / 2));
            y = (int)(Position.Y - (h / 2));
        }
        else
        {
            x = (int)Position.X;
            y = (int)Position.Y;
            w = Width;
            h = Height;
        }
        return new Rectangle(x, y, w, h);
    }
}

This is it here. In my work in the edit, I accidentally had Math.Cos in the sin variable, which didn't help.

So it's just basic trigonometry. If the textures angle is something other than zero, calculate the sides of the two triangles formed by the width and the height, and use the sides as the values for the width and the height, then center the rectangle around the texture. If that makes sense.

Here's a picture to help explain:

Solve

Here's a gif of the final result:

enter image description here