如何旋转二维向量?

16

我有这个:

static double[] RotateVector2d(double x, double y, double degrees)
{
    double[] result = new double[2];
    result[0] = x * Math.Cos(degrees) - y * Math.Sin(degrees);
    result[1] = x * Math.Sin(degrees) + y * Math.Cos(degrees);
    return result;
}

当我打电话时

RotateVector2d(1.0, 0, 180.0)

结果为:[-0.59846006905785809, -0.80115263573383044]

如何使结果变为[-1, 0]

我做错了什么?


4
文档说明Math.Cos期望一个双精度浮点数d作为参数,应该改为double r或double radians以明确意义。 - Martin Meeser
4个回答

26

谢谢你也(你比J晚了4秒...) - Martin Meeser
1
@MartinMeeser 按我的时钟,他比我快了8秒。 - J...
首先!开个玩笑,我真的不在意。 - reggaeguitar
@J...好的,我将这个标记为答案并点赞了你的回答,你们两个都是正确的,而且同时。 - Martin Meeser

25

有几件事情:

使用Vector表示向量。

  • v.Xv[0]更易读
  • 它是一个结构,因此性能很好。
  • 请注意,Vector是可变的结构。

对于旋转,也许扩展方法是有意义的:

using System;
using System.Windows;

public static class VectorExt
{
    private const double DegToRad = Math.PI/180;

    public static Vector Rotate(this Vector v, double degrees)
    {
        return v.RotateRadians(degrees * DegToRad);
    }

    public static Vector RotateRadians(this Vector v, double radians)
    {
        var ca = Math.Cos(radians);
        var sa = Math.Sin(radians);
        return new Vector(ca*v.X - sa*v.Y, sa*v.X + ca*v.Y);
    }
}

1
为了获取一个向量结构而包含整个 System.Windows 命名空间?我认为这不是一个好思路,也不会有良好的性能。我认为这个命名空间是专门用于 WinForms 的。 - Martin Meeser
我也不同意v.X比v[0]更易读,我认为大家都认为可以使用v[x,y,z]。 - Martin Meeser
关于引入 System.Windows 的观点是有道理的,但框架中其他地方也有矢量。或者自己实现。关于可读性:在我看来,使用 Vector 而不是 double[] 不能在同一天进行比较。关于性能:没有进行基准测试,我预计结构体要比使用 double[] 快约 ~1000 倍。 - Johan Larsson
1
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Johan Larsson
3
数组比结构体慢,因为数组需要边界检查,而且数组是引用对象,而结构体是值对象。结构体更好,因为它们是类型安全的(而且更易读)。另外,System.Windows.Vector是WPF,而不是WinForms。还有,造成开销的是程序集而不是命名空间,但对性能没有什么显著影响。如果你不使用WPF,并且有充分合理的理由不包含它,那么只需定义自己的Vector结构体即可。 - Jim Balter
显示剩余2条评论

5

SinCos的取值是弧度制,而非角度制。180度等于Math.PI弧度。


1

如果您想使用矩阵而无需转换就能使用度数的替代方法:

    System.Windows.Media.Matrix m = new System.Windows.Media.Matrix();
    m.Rotate((double)angle_degrees);
    System.Windows.Vector v = new System.Windows.Vector(x,y);
    v = System.Windows.Vector.Multiply(v, m);

你能否为矩阵和向量添加命名空间? 在我的情况下,仅为了解决这个问题添加大量的命名空间是一种负担。 - Martin Meeser
是的,这是需要考虑的事情。在我的情况下,我已经在我的应用程序中使用了这些命名空间,对我来说,这个解决方案比其他答案更容易。 - Alex G. G.
正如其他答案中所指出的那样,System.Windows是一个WinForms特定的命名空间。如果我错了,请纠正我。 - Martin Meeser
似乎与我用于用户界面的WPF相关。对于非WPF应用程序来说,仅为此包含它可能有些过多。 - Alex G. G.
@MartinMeeser 你错了,应该是WPF。System.Windows.Forms是WinForms。 - Jim Balter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接