我知道这可能是一个非常简单的问题,但我似乎无法弄明白。首先,我想指出我确实在半小时左右的时间内查看Google和SO,但没有找到我的问题的答案(是的,我很认真)。
基本上,我想围绕一个点旋转一个Vector2(在我的例子中,它总是(0,0)向量)。因此,我尝试使用参数作为旋转点和旋转角度(以度为单位)来创建函数。
这是一张快速绘图,展示了我正在努力实现的目标:
我想取V1(红色矢量),将其旋转角度A(蓝色),以获得新的矢量(V2,绿色)。在这个例子中,我使用了一个最简单的情况:轴上的V1和90度角,但我希望该函数能够处理更多的“复杂的”情况。
所以这是我的功能:
public static Vector2 RotateVector2(Vector2 point, float degrees)
{
return Vector2.Transform(point,
Matrix.CreateRotationZ(MathHelper.ToRadians(degrees)));
}
那么,我做错了什么?当我运行代码并使用(0,-1)向量和90度角调用此函数时,我得到向量(1,4.3111139E-08)......
另外,如果我想接受一个点作为参数旋转呢?因此旋转并不总是发生在(0,0)...
周围答案 0 :(得分:6)
Chris Schmich关于浮点精度和使用弧度的答案是正确的。我建议使用RotateVector2的替代实现,并回答问题的第二部分。
构建4x4旋转矩阵以旋转矢量将导致大量不必要的操作。矩阵变换实际上是在执行以下操作,但使用了大量冗余数学:
public static Vector2 RotateVector2(Vector2 point, float radians)
{
float cosRadians = (float)Math.Cos(radians);
float sinRadians = (float)Math.Sin(radians);
return new Vector2(
point.X * cosRadians - point.Y * sinRadians,
point.X * sinRadians + point.Y * cosRadians);
}
如果要围绕任意点旋转,首先需要平移空间,以便旋转的点是原点,旋转然后反转平移。
public static Vector2 RotateVector2(Vector2 point, float radians, Vector2 pivot)
{
float cosRadians = (float)Math.Cos(radians);
float sinRadians = (float)Math.Sin(radians);
Vector2 translatedPoint = new Vector2();
translatedPoint.X = point.X - pivot.X;
translatedPoint.Y = point.Y - pivot.Y;
Vector2 rotatedPoint = new Vector2();
rotatedPoint.X = translatedPoint.X * cosRadians - translatedPoint.Y * sinRadians + pivot.X;
rotatedPoint.Y = translatedPoint.X * sinRadians + translatedPoint.Y * cosRadians + pivot.Y;
return rotatedPoint;
}
请注意,向量运算已内联以获得最大速度。
答案 1 :(得分:3)
那么,我做错了什么?当我运行代码并使用(0,-1)向量和90度角调用此函数时,我得到向量(1,4.3111139E-08)......
您的代码是正确的,这只是一个浮点表示问题。 4.371139E-08基本上为零(它是0.0000000431139),但转换没有产生恰好为零的值。这是您应该注意的浮点的常见问题。 This SO answer对浮点有一些额外的好处。
另外,如果可能的话,你应该坚持使用弧度而不是使用度数。这可能会在计算中引入更多错误。