【问题标题】:2D Euclidean vector rotations2D 欧几里得矢量旋转
【发布时间】:2011-01-24 08:52:39
【问题描述】:

我有一个欧几里得向量a 位于坐标(0, 1)。 我想将a 绕原点旋转 90 度(顺时针):(0, 0)

如果我对它的工作原理有正确的理解,那么旋转后的结果 (x, y) 坐标应该是(1, 0)。 如果我将它旋转 45 度(仍然是顺时针),我会期望得到的坐标是 (0.707, 0.707)

theta = deg2rad(angle);

cs = cos(theta);
sn = sin(theta);

x = x * cs - y * sn;
y = x * sn + y * cs;

使用上面的代码,angle 的值为 90.0 度,结果坐标为:(-1, 1)。 我真是太糊涂了。 以下链接中的示例肯定代表了上面显示的相同公式吗?

我做错了什么? 还是我误解了矢量是如何旋转的?

【问题讨论】:

  • 所有变量的类型是什么?
  • 双打,但答案很简单,感谢 Caspar。
  • 还有——这不是逆时针吗?

标签: c++ math vector rotation trigonometry


【解决方案1】:

将矢量旋转 90 度特别简单。

(x, y) 围绕(0, 0) 旋转 90 度是(-y, x)

如果你想顺时针旋转,你只需反过来做,得到(y, -x)

【讨论】:

  • +1。对于为计算机屏幕旋转 2D 矢量的任何人:此答案假定 y 轴与数学一样指向上方。如果它在计算机屏幕上指向下方,则顺时针和逆时针方向相反。 (-y, x) 是顺时针,(y, -x) 是逆时针。
【解决方案2】:

你应该从函数中删除变量:

x = x * cs - y * sn; // now x is something different than original vector x
y = x * sn + y * cs;

创建新坐标变为,避免在到达第二行之前计算x:

px = x * cs - y * sn; 
py = x * sn + y * cs;

【讨论】:

  • 哦,天哪,我需要新鲜的眼睛......再次如此明显......谢谢伙计(工作一个美女,2小时后......哈哈)
  • 当你执行 x = x * cs - y * sn; 时,它会给 x in y = x * sn + y * cs 一个不同的值,所以 x 会“脱轨”
  • @Daniel:第二条语句中的 x 在您使用它计算 y 的值时已经改变了它的值。因此,基本上,您计算了旋转 (0,1) 的 x 坐标(即 -1)。然后你把它存储在 x 坐标中给出 (-1,1) 然后你计算了旋转的 y 坐标 (-1,1) (实际上应该是 -1,所以我不确定你是怎么得到的 (-1 ,1) 而不是 (-1,-1) )。顺便说一句,正确的答案不是 (1,0),而是 (-1,0),因为从上方看,正角度的旋转是逆时针方向的。
  • 这个 YouTube series 将让您对旋转/更改基础有一个深刻的直观理解!
【解决方案3】:

围绕 0,0 旋转 90 度:

x' = -y
y' = x

围绕 px,py 旋转 90 度:

x' = -(y - py) + px
y' = (x - px) + py

【讨论】:

    【解决方案4】:

    使用标准类听起来更容易:

    std::complex<double> vecA(0,1);
    std::complex<double> i(0,1); // 90 degrees
    std::complex<double> r45(sqrt(2.0),sqrt(2.0));
    vecA *= i;
    vecA *= r45;
    

    向量旋转是复数乘法的一个子集。要旋转角度alpha,乘以std::complex&lt;double&gt; { cos(alpha), sin(alpha) }

    【讨论】:

    • 注意这个方法不需要计算正弦或余弦
    • TBH 这是因为 r45 是预先计算好的。
    【解决方案5】:

    您正在根据新坐标的“新”x 部分计算新坐标的 y 部分。基本上这意味着您根据新输出计算新输出...

    尝试在输入输出方面重写:

    vector2<double> multiply( vector2<double> input, double cs, double sn ) {
      vector2<double> result;
      result.x = input.x * cs - input.y * sn;
      result.y = input.x * sn + input.y * cs;
      return result;
    }
    

    那么你可以这样做:

    vector2<double> input(0,1);
    vector2<double> transformed = multiply( input, cs, sn );
    

    注意为变量选择合适的名称可以完全避免这个问题!

    【讨论】:

      猜你喜欢
      • 2018-11-13
      • 2016-02-18
      • 1970-01-01
      • 2019-09-14
      • 2023-01-16
      • 1970-01-01
      • 2016-08-06
      • 2013-03-02
      相关资源
      最近更新 更多