How could i calculate the "furthest out" edges of a sprite to create a rectangular outline around a transformed sprite with an origin?
I want to achieve something like this http://oi43.tinypic.com/14l39k0.jpg http://i42.tinypic.com/2m62v41.png where the red box is the "outline" and the black box is the transformed sprite. The box needs to expand based on the corner - just a bounding box really.
I've tried various equations liked this to find the coordinates of a transformed sprite:
Transformed.X = pos.X * (float)Math.Cos(angle) - pos.Y * (float)Math.Sin(angle); Transformed.Y = pos.X * (float)Math.Sin(angle) + pos.Y * (float)Math.Cos(angle);
but i can't seem to make it work. Any ideas how i can achieve this?
Any help would be appreciated.
Juan
With thanks to Zenchovey i was able to solve my problem. Here's the code i used:
Initiating variables
Vector2 TransformPos = Vector2.Zero;
Vector2 TransformPos2 = Vector2.Zero;
float[] px = new float[2];
float[] py = new float[2];
float[] pxl = new float[2];
float[] pyl = new float[2];
float ox;
float oy;
Update Method
// Vars
ox = pos.X;
oy = pos.Y;
// top left
pxl[0] = pos.X - Origin.X;
pyl[0] = pos.Y - Origin.Y;
// bottom left
pxl[1] = pos.X - Origin.X;
pyl[1] = pos.Y + Origin.Y;
// top right
px[0] = pos.X + Origin.X;
py[0] = pos.Y - Origin.Y;
// bottom right
px[1] = pos.X + Origin.X;
py[1] = pos.Y + Origin.Y;
if (rot <= MathHelper.ToRadians(90) && rot >= MathHelper.ToRadians(0))
{
TransformPos.X = (float)Math.Cos(rot) * (pxl.Min() - ox) - (float)Math.Sin(rot) * (pyl.Max() - oy) + ox;
TransformPos.Y = (float)Math.Sin(rot) * (pxl.Min() - ox) + (float)Math.Cos(rot) * (pyl.Min() - oy) + oy;
TransformPos2.X = (float)Math.Cos(rot) * (px.Max() - ox) - (float)Math.Sin(rot) * (py.Min() - oy) + ox;
TransformPos2.Y = (float)Math.Sin(rot) * (px.Max() - ox) + (float)Math.Cos(rot) * (py.Max() - oy) + oy;
}
else
if (rot <= MathHelper.ToRadians(270) && rot >= MathHelper.ToRadians(180))
{
TransformPos2.X = (float)Math.Cos(rot) * (pxl.Min() - ox) - (float)Math.Sin(rot) * (pyl.Max() - oy) + ox;
TransformPos2.Y = (float)Math.Sin(rot) * (pxl.Min() - ox) + (float)Math.Cos(rot) * (pyl.Min() - oy) + oy;
TransformPos.X = (float)Math.Cos(rot) * (px.Max() - ox) - (float)Math.Sin(rot) * (py.Min() - oy) + ox;
TransformPos.Y = (float)Math.Sin(rot) * (px.Max() - ox) + (float)Math.Cos(rot) * (py.Max() - oy) + oy;
}
else
if (rot <= MathHelper.ToRadians(180) && rot >= MathHelper.ToRadians(90))
{
TransformPos2.X = (float)Math.Cos(rot) * (pxl.Max() - ox) - (float)Math.Sin(rot) * (pyl.Min() - oy) + ox;
TransformPos.Y = (float)Math.Sin(rot) * (pxl.Max() - ox) + (float)Math.Cos(rot) * (pyl.Max() - oy) + oy;
TransformPos.X = (float)Math.Cos(rot) * (px.Min() - ox) - (float)Math.Sin(rot) * (py.Max() - oy) + ox;
TransformPos2.Y = (float)Math.Sin(rot) * (px.Min() - ox) + (float)Math.Cos(rot) * (py.Min() - oy) + oy;
}
else
if (rot <= MathHelper.ToRadians(360) && rot >= MathHelper.ToRadians(270))
{
TransformPos.X = (float)Math.Cos(rot) * (pxl.Max() - ox) - (float)Math.Sin(rot) * (pyl.Min() - oy) + ox;
TransformPos2.Y = (float)Math.Sin(rot) * (pxl.Max() - ox) + (float)Math.Cos(rot) * (pyl.Max() - oy) + oy;
TransformPos2.X = (float)Math.Cos(rot) * (px.Min() - ox) - (float)Math.Sin(rot) * (py.Max() - oy) + ox;
TransformPos.Y = (float)Math.Sin(rot) * (px.Min() - ox) + (float)Math.Cos(rot) * (py.Min() - oy) + oy;
}
Transform = new Rectangle((int)TransformPos.X, (int)TransformPos.Y, (int)TransformPos2.X - (int)TransformPos.X, (int)TransformPos2.Y - (int)TransformPos.Y);
It looks for the max and min values of the sprite's corner based on it's rotation to make the bounding box. The code is assuming that the origin is the middle of the sprite, you will have to change the code based on the origin
If you find the position of each corner on the unrotated sprite and then rotate them about point you did your rotation to find the each corner of the rotated sprite. (How to do this is described here)
Then you can just find the max and min x and y values of these points. The minX and minY will be the top left of your bounding rect and the maxX and maxY will be the bottom right of your bounding rect.