这个 XNA RotateVector2 函数有什么问题?

发布于 2024-09-24 09:40:44 字数 751 浏览 1 评论 0原文

我知道这可能是一个非常简单的问题,但我似乎无法弄清楚。首先,我想说明的是,我确实在谷歌和SO上搜索了半个小时左右,但没有找到我问题的答案(是的,我是认真的)。

基本上,我想围绕一个点旋转 Vector2(在我的例子中,该点始终是 (0, 0) 向量)。因此,我尝试创建一个函数来执行此操作,其参数是旋转点和旋转角度(以度为单位)。

这是一张快速绘图,显示了我想要实现的目标:

alt text

我想采用 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.371139E-08) ...

另外,如果我想接受一个点怎么办旋转也作为参数吗?这样旋转并不总是围绕 (0, 0) 发生......

I know this is probably a very simple question, but I can't seem to figure it out. First of all, I want to specify that I did look over Google and SO for half an hour or so without finding the answer to my question(yes, I am serious).

Basically, I want to rotate a Vector2 around a point(which, in my case, is always the (0, 0) vector). So, I tried to make a function to do it with the parameters being the point to rotate and the angle(in degrees) to rotate by.

Here's a quick drawing showing what I'm trying to achieve:

alt text

I want to take V1(red vector), rotate it by an angle A(blue), to obtain a new vector (V2, green). In this example I used one of the simplest case: V1 on the axis, and a 90 degree angle, but I want the function to handle more "complicated" cases too.

So here's my function:

public static Vector2 RotateVector2(Vector2 point, float degrees)
{
    return Vector2.Transform(point, 
    Matrix.CreateRotationZ(MathHelper.ToRadians(degrees)));
}

So, what am I doing wrong? When I run the code and call this function with the (0, -1) vector and a 90 degrees angle, I get the vector (1, 4.371139E-08) ...

Also, what if I want to accept a point to rotate around as a parameter too? So that the rotation doesn't always happen around (0, 0)...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

So要识趣 2024-10-01 09:40:44

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;
    }

请注意,矢量算术已内联以获得最大速度。

Chris Schmich's answer regarding floating point precision and using radians is correct. I suggest an alternate implementation for RotateVector2 and answer the second part of your question.

Building a 4x4 rotation matrix to rotate a vector will cause a lot of unnecessary operations. The matrix transform is actually doing the following but using a lot of redundant math:

    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);
    }

If you want to rotate around an arbitrary point, you first need to translate your space so that the point to be rotated around is the origin, do the rotation and then reverse the translation.

    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;
    }

Note that the vector arithmetic has been inlined for maximum speed.

最终幸福 2024-10-01 09:40:44

那么,我做错了什么?当我运行代码并使用 (0, -1) 向量和 90 度角调用此函数时,我得到向量 (1, 4.371139E-08) ...

您的代码是正确的,这只是一个浮点代表性问题。 4.371139E-08 本质上为零(它是 0.0000000431139),但转换并未产生完全为零的值。这是您应该注意的浮点常见问题。 这个答案有一些关于浮动的额外优点观点。

另外,如果可能的话,您应该坚持使用弧度而不是度数。这可能会给您的计算带来更多错误。

So, what am I doing wrong? When I run the code and call this function with the (0, -1) vector and a 90 degrees angle, I get the vector (1, 4.371139E-08) ...

Your code is correct, this is just a floating point representation issue. 4.371139E-08 is essentially zero (it's 0.0000000431139), but the transformation did not produce a value that was exactly zero. This is a common problem with floating point that you should be aware of. This SO answer has some additional good points about floating point.

Also, if possible, you should stick with radians instead of using degrees. This is likely introducing more error into your computations.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文