根据两个向量计算方向角?

发布于 2024-08-28 02:39:09 字数 219 浏览 10 评论 0原文

假设我有两个 2D 向量,一个用于对象的当前位置,一个用于该对象的先前位置。如何计算出行进的角度方向?

此图片可能有助于理解我所追求的内容:

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

Say I have two 2D vectors, one for an objects current position and one for that objects previous position. How can I work out the angular direction of travel?

This image might help understand what I'm after:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

っ左 2024-09-04 02:39:09

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

d = (x1, y1) - (x, y) = (x1 - x, y1 - y)

现在当您询问方向角时,这取决于您想要测量角度的方向。是相对于x轴吗?接受拉杜的回答。针对任意向量?请参阅 Justjeff 的回答。

编辑:要获取相对于 y 轴的角度:

tan (theta) = (x1 -x)/(y1 - y)          

角度的正切是差值向量的 x 坐标与差值向量的 y 坐标之比。

所以

theta = arctan[(x1 - x)/(y1 - y)]

其中 arctan 表示反正切。不要与正切的倒数混淆,很多人都会这样做,因为它们都经常表示为 tan^-1。并确保您知道您使用的是度数还是弧度。

The direction vector of travel will be the difference of the two position vectors,

d = (x1, y1) - (x, y) = (x1 - x, y1 - y)

Now when you ask for the direction angle, that depends what direction you want to measure the angle against. Is it against the x axis? Go with Radu's answer. Against an arbitrary vector? See justjeff's answer.

Edit: To get the angle against the y-axis:

tan (theta) = (x1 -x)/(y1 - y)          

the tangent of the angle is the ratio of the x-coordinate of the difference vector to the y-coordinate of the difference vector.

So

theta = arctan[(x1 - x)/(y1 - y)]

Where arctan means inverse tangent. Not to be confused with the reciprocal of the tangent, which many people do, since they're both frequently denoted tan^-1. And make sure you know whether you're working in degrees or radians.

雨后彩虹 2024-09-04 02:39:09

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

double theta = atan2(x1-x, y1-y);

这个角度将是从垂直轴开始的,正如你所标记的,并且将以弧度(上帝自己的角度单位)为单位进行测量。

If you're in C (or other language that uses the same function set) then you're probably looking for the atan2() function. From your diagram:

double theta = atan2(x1-x, y1-y);

That angle will be from the vertical axis, as you marked, and will be measured in radians (God's own angle unit).

凡间太子 2024-09-04 02:39:09

请小心使用 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长度这将会失败。所以你可能想以某种方式捕获它。

Be careful to use atan2 to avoid quadrant issues and division by zero. That's what it's there for.

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;
}

However, if you don't care about whether it's a +ve or -ve angle, just use the dot product rule (less CPU load):

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;
}

Note that in either code section above, if one ( or both ) vectors are close to 0 length this is going to fail. So you might want to trap that somehow.

一个人练习一个人 2024-09-04 02:39:09

仍然不确定旋转矩阵的含义,但这是从方向向量获取方位角的简单情况。

复杂的答案:

通常,您应该将一些转换/实用函数与 2D 向量打包在一起:用于从 X,Y(笛卡尔)转换为 Theta,R(极坐标)的函数。您还应该支持基本的向量运算,例如加法、减法和点积。
在这种情况下,您的答案是:

 double azimuth  =  (P2 - P1).ToPolarCoordinate().Azimuth;

其中 ToPolarCooperative() 和 ToCarhtesianCooperative() 是从一种矢量类型切换到另一种矢量类型的两个倒数函数。

简单的:

 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
 }

Still not sure what you mean by rotation matrices, but this is a simple case of getting an azimuth from a direction vector.

The complicated answer:

Normally you should pack a few conversion/utility functions with your 2D vectors: one to convert from X,Y (carthesian) to Theta,R (polar coordinates). You should also support basic vector operations like addition, substraction and dot product.
Your answer in this case would be:

 double azimuth  =  (P2 - P1).ToPolarCoordinate().Azimuth;

Where ToPolarCoordinate() and ToCarhtesianCoordinate() are two reciprocal functions switching from one type of vector to another.

The simple one:

 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
 }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文