XNA/Monogame 无论旋转如何围绕纹理创建矩形?
XNA/Monogame Creating rectangle around texture regardless of rotation?
我知道 Rectangle
是轴对齐的,没关系,我只是不知道如何创建一个矩形,所以它总是包含整个精灵,无论旋转如何。我一直在到处寻找答案,但我无法在任何地方得到一个直接的答案。
例如:
假设原点是纹理的中间,我该怎么办?
编辑
稍微摆弄了一下,我已经走到这一步了:
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);
}
}
(我突然想到这样做..但原则应该有效)
创建一个围绕矩形中心旋转的矩阵 - 即 -(x+width/2), -(y+height/2) 的平移
然后旋转角度
然后是 (x+width/2), (y+height/2)
的翻译
使用Vector2.Transform变换原矩形的每个角
然后制作一个新的矩形
x = min(p1.x, p2.x, p3.x, p4.x)
宽度 = max(p1.x, p2.x, p3.x, p4.x) - x
y 相似
抱歉,这么晚才来,但我刚才想出来了,忘了 post 一个答案。
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);
}
}
就是这里。在我的编辑工作中,我不小心在 sin
变量中包含了 Math.Cos
,这没有帮助。
所以这只是基本的三角函数。如果纹理角度不是零,则计算由宽度和高度形成的两个三角形的边,并将边用作宽度和高度的值,然后将矩形围绕纹理居中。如果说得通。
这里有一张图来帮助解释:
这是最终结果的 gif:
我知道 Rectangle
是轴对齐的,没关系,我只是不知道如何创建一个矩形,所以它总是包含整个精灵,无论旋转如何。我一直在到处寻找答案,但我无法在任何地方得到一个直接的答案。
例如:
假设原点是纹理的中间,我该怎么办?
编辑
稍微摆弄了一下,我已经走到这一步了:
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);
}
}
(我突然想到这样做..但原则应该有效)
创建一个围绕矩形中心旋转的矩阵 - 即 -(x+width/2), -(y+height/2) 的平移 然后旋转角度 然后是 (x+width/2), (y+height/2)
的翻译使用Vector2.Transform变换原矩形的每个角
然后制作一个新的矩形 x = min(p1.x, p2.x, p3.x, p4.x) 宽度 = max(p1.x, p2.x, p3.x, p4.x) - x
y 相似
抱歉,这么晚才来,但我刚才想出来了,忘了 post 一个答案。
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);
}
}
就是这里。在我的编辑工作中,我不小心在 sin
变量中包含了 Math.Cos
,这没有帮助。
所以这只是基本的三角函数。如果纹理角度不是零,则计算由宽度和高度形成的两个三角形的边,并将边用作宽度和高度的值,然后将矩形围绕纹理居中。如果说得通。
这里有一张图来帮助解释:
这是最终结果的 gif: