从两个向量计算方向角?

ing*_*.am 12 algorithm vector angle

假设我有两个2D矢量,一个用于对象当前位置,另一个用于该对象之前的位置.我怎样才能计算出旅行的角度方向?

这张图片可能有助于了解我的目标:

(图片)http://files.me.com/james.ingham/crcvmy

Rob*_*lan 10

行进的方向向量将是两个位置向量的差异,

d = (x1, y1) - (x, y) = (x1 - x, y1 - y)
Run Code Online (Sandbox Code Playgroud)

现在当你要求方向角时,这取决于你想要测量角度的方向.它是否与x轴相对应?和Radu一起回答.反对任意向量?见justjeff的答案.

编辑:要获得与y轴的角度:

tan (theta) = (x1 -x)/(y1 - y)          
Run Code Online (Sandbox Code Playgroud)

角度的正切是差矢量的x坐标与差矢量的y坐标的比率.

所以

theta = arctan[(x1 - x)/(y1 - y)]
Run Code Online (Sandbox Code Playgroud)

其中arctan表示反正切.不要与许多人所做的切线的倒数混淆,因为它们经常被称为tan ^ -1.并确保你知道你是以度数还是弧度工作.

  • @james`arctan`在某些角度有问题(即,如果除以零).这就是为什么有'atan2`正确处理棘手案件的原因. (6认同)

Don*_*ows 9

如果您使用C语言(或使用相同功能集的其他语言),那么您可能正在寻找该atan2()功能.从你的图表:

double theta = atan2(x1-x, y1-y);
Run Code Online (Sandbox Code Playgroud)

当您标记时,该角度将来自垂直轴,并将以弧度(上帝自己的角度单位)进行测量.


P i*_*P i 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;
}
Run Code Online (Sandbox Code Playgroud)

但是,如果您不关心它是+ 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;
}
Run Code Online (Sandbox Code Playgroud)

请注意,在上面的任一代码部分中,如果一个(或两个)向量接近0长度,则这将失败.所以你可能想以某种方式陷阱.