2D欧几里德矢量旋转

时间:2011-01-24 08:52:40

标签: c++ math vector rotation trigonometry

我在坐标a处有一个欧几里德矢量(0, 1)。 我想围绕原点a(0, 0)旋转90度(顺时针)。

如果我正确理解它应该如何工作,旋转后的结果(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)。 而我真的很困惑。 以下链接中的示例代表了上面显示的相同公式吗?

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

5 个答案:

答案 0 :(得分:75)

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

<(x, y)(0, 0)周围旋转90度为(-y, x)

如果你想顺时针旋转,你可以反过来做,(y, -x)

答案 1 :(得分:69)

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

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 :(得分:18)

围绕0,0旋转90度:

x' = -y
y' = x

围绕px旋转90度,py:

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

答案 3 :(得分: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 );

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

答案 4 :(得分:5)

标准类更容易理解:

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;

矢量旋转是复数乘法的一个子集..