【问题标题】:Algorithm for finding new points of rotating a vector寻找旋转向量的新点的算法
【发布时间】:2021-08-25 20:39:36
【问题描述】:

我正在尝试以编程方式找到通过围绕其原点旋转矢量创建的点(可能在 2D 空间中的任何位置)。

我们看到我们在 (x, y) 的某个点上有我们的线(或数学向量)A,它可能位于 2D 空间中的任何位置。它在某个 (x, y) 处运行到点 B。我们将它旋转 Theta,然后移动到 (x, y) 处的某个点 C。对我来说,问题在于尝试以编程方式使用数学来解决这些问题。

最初的想法是形成一个三角形并使用 trig,但这个角度可能正好是 180(不太可能但可能),显然没有三角形可以工作。有人有想法吗?

我正在使用 C# 和我自己的矢量对象(如下)来测试线条的创建。任何帮助表示赞赏!

struct Vector2D {
    double x, y, theta;
    Vector2D(double x, double y) {
        (this.x, this.y) = (x, y);
        theta = x != 0 ? Math.Atan(y / x) : 0;
    }
    double Magnitude() {
        return Math.Sqrt(Math.Pow(x, 2) + Math.Pow(y, 2));
    }
    (double,double) PointFromRotation(double angle) {
        // This is where I need some help...
        
        return (0,0); // hopefully a point of x and y from the angle argument
    }
}

【问题讨论】:

  • 听起来像线性变换是你的朋友吗?您可以将向量平移到原点(0,0),然后使用旋转矩阵对其进行旋转,然后将其平移回原始位置。

标签: c# algorithm math


【解决方案1】:

我认为最好使用以下代码。 我对您的代码做了一些小的修改和补充。

“theta”的计算部分略有修改。 并且,您可以从以下网址参考旋转算法。

Rotation (mathematics)

struct Vector2D
{
    public double x;
    public double y;
    public double theta;

    public Vector2D(double x, double y)
    {
        (this.x, this.y) = (x, y);
        theta = x != 0 ? Math.Atan(y / x) : Math.Sign(y) * Math.PI / 2.0;
    }

    public double Magnitude()
    {
        return Math.Sqrt(Math.Pow(x, 2) + Math.Pow(y, 2));
    }

    public (double x, double y) PointFromRotation(double angle)
    {
        double Sint = Math.Sin(angle);
        double Cost = Math.Cos(angle);

        double rX = x * Cost - y * Sint;
        double rY = x * Sint + y * Cost;

        return (rX, rY);
    }
}

【讨论】:

  • 这完全有效。感谢您添加到 theta 的分配中。我不是很精通数学,但我确实尝试自己编写所有代码。
  • 很高兴它帮助了你。
【解决方案2】:

您可以将笛卡尔坐标(x, y)转换为极坐标坐标(R, fi), 将theta 添加到fi 然后转换回笛卡尔:

// Rotate B around A by angle theta
private static (double x, double y) Rotate(
  (double x, double y) A, 
  (double x, double y) B, 
  double theta) {
  
  double fi = Math.Atan2(B.y - A.y, B.x - A.x) + theta;
  double R = Math.Sqrt((A.y - B.y) * (A.y - B.y) + (A.x - B.x) * (A.x - B.x));

  return (A.x + R * Math.Cos(fi), A.y + R * Math.Sin(fi));
}

唯一可能的困难是计算fi,这可以在Math.Atan2方法的帮助下完成。

【讨论】:

  • 啊,是的,这是我记得在数学课上说我真的应该注意的地方,因为它可能有一天会回到我身边……不过,这将是一个非常好的静态方法!跨度>
  • 我实际上直到最近才有权投票,因为我没有足够的评论。所以我很乐意在堆栈溢出方面支持更多的东西。希望我能帮助那些有需要的人,并且我已经在这个网站上找到了一切。
【解决方案3】:

另一种选择:

// Rotate B around A by angle theta clockwise
private static (double x, double y) Rotate(
      (double x, double y) A,
      (double x, double y) B,
      double theta)
{
        double s = Math.Sin(theta);
        double c = Math.Cos(theta);

        // translate point back to origin:
        B.x -= A.x;
        B.y -= A.y;

        // rotate point clockwise
        double xnew = B.x * c - B.y * s;
        double ynew = B.x * s + B.y * c;

        // translate point back:
        B.x = xnew + A.x;
        B.y = ynew + A.y;

        return B;
}

灵感来自this 答案

【讨论】:

  • 这对查看也很有帮助,感谢原始帖子的链接。用向量作为主要术语我找不到任何直接的答案,但它们最终只是点。
猜你喜欢
  • 2011-02-07
  • 2011-05-04
  • 2010-10-24
  • 2010-12-23
  • 1970-01-01
  • 2020-01-27
  • 1970-01-01
  • 2012-04-29
  • 2011-11-29
相关资源
最近更新 更多