假设我有两个2D矢量,一个用于对象当前位置,另一个用于该对象之前的位置。我怎样才能计算出旅行的角度方向?
此图片可能有助于了解我的目标:
答案 0 :(得分:10)
行进方向矢量将是两个位置矢量的差值
d = (x1, y1) - (x, y) = (x1 - x, y1 - y)
现在,当您询问方向角时,这取决于您想要测量角度的方向。它是否与x轴相对应?和Radu一起回答。反对任意向量?见justjeff的答案。
编辑:要获得与y轴的角度:
tan (theta) = (x1 -x)/(y1 - y)
角度的正切是差矢量的x坐标与差矢量的y坐标之比。
所以
theta = arctan[(x1 - x)/(y1 - y)]
其中arctan表示反正切。不要与许多人所做的切线的倒数混淆,因为它们经常被称为tan ^ -1。并确保你知道你是以度数还是弧度工作。
答案 1 :(得分:9)
如果您使用的是C(或使用相同功能集的其他语言),那么您可能正在寻找atan2()
功能。从你的图表:
double theta = atan2(x1-x, y1-y);
当您标记时,该角度将来自垂直轴,并将以弧度(上帝自己的角度单位)进行测量。
答案 2 :(得分:5)
小心使用atan2来避免象限问题并将其除以零。这就是它的用途。
float getAngle(CGPoint ptA, CGPoint ptOrigin, CGPoint ptB)
{
CGPoint A = makeVec(ptOrigin, ptA);
CGPoint B = makeVec(ptOrigin, ptB);
// angle with +ve x-axis, in the range (−π, π]
float thetaA = atan2(A.x, A.y);
float thetaB = atan2(B.x, B.y);
float thetaAB = thetaB - thetaA;
// get in range (−π, π]
while (thetaAB <= - M_PI)
thetaAB += 2 * M_PI;
while (thetaAB > M_PI)
thetaAB -= 2 * M_PI;
return thetaAB;
}
但是,如果您不关心它是+ ve还是-ve角,只需使用点积规则(减去CPU负载):
float dotProduct(CGPoint p1, CGPoint p2) { return p1.x * p2.x + p1.y * p2.y; }
float getAngle(CGPoint A, CGPoint O, CGPoint B)
{
CGPoint U = makeVec(O, A);
CGPoint V = makeVec(O, B);
float magU = vecGetMag(U);
float magV = vecGetMag(V);
float magUmagV = magU * magV; assert (ABS(magUmagV) > 0.00001);
// U.V = |U| |V| cos t
float cosT = dotProduct(U, V) / magUmagV;
float theta = acos(cosT);
return theta;
}
请注意,在上面的任一代码部分中,如果一个(或两个)向量接近0长度,则这将失败。所以你可能想以某种方式陷阱。
答案 3 :(得分:2)
仍然不确定旋转矩阵是什么意思,但这是从方向向量获取方位角的简单情况。
复杂的答案:
通常你应该用2D矢量打包几个转换/效用函数:一个用于从X,Y(carthesian)转换为Theta,R(极坐标)。您还应该支持基本矢量操作,如加法,减法和点积。 在这种情况下你的答案是:
double azimuth = (P2 - P1).ToPolarCoordinate().Azimuth;
ToPolarCoordinate()和ToCarhtesianCoordinate()是从一种矢量切换到另一种矢量的两个互惠函数。
简单的一句:
double azimuth = acos ((x2-x1)/sqrt((x2-x1) * (x2-x1) + (y2-y1) * (y2-y1));
//then do a quadrant resolution based on the +/- sign of (y2-y1) and (x2-x1)
if (x2-x1)>0 {
if (y2-y1)<0 { azimuth = Pi-azimuth; } //quadrant 2
} else
{ if (y2-y1)> 0 { azimuth = 2*Pi-azimuth;} //quadrant 4
else { azimuth = Pi + azimuth;} //quadrant 3
}