使用atan2找到两个向量之间的角度

use*_*201 45 math geometry vector

我明白那个:

atan2(vector.y, vector.x)= 矢量和X轴之间的角度.

但我想知道如何使用atan2 获得两个向量之间的角度.所以我遇到了这个解决方案:

atan2(vector1.y - vector2.y, vector1.x - vector2.x)
Run Code Online (Sandbox Code Playgroud)

我的问题很简单:

以下两个公式会产生相同的数字吗?

  • atan2(vector1.y - vector2.y, vector1.x - vector2.x)

  • atan2(vector2.y - vector1.y, vector2.x - vector1.x)

如果不是:我怎么知道减法中哪个矢量首先出现?

谢谢

Mar*_*n R 99

 atan2(vector1.y - vector2.y, vector1.x - vector2.x)
Run Code Online (Sandbox Code Playgroud)

差矢量(连接矢量2矢量 1)和x轴之间的角度,这可能不是你的意思.

从vector1到vector2的(定向)角度可以计算为

angle = atan2(vector2.y, vector2.x) - atan2(vector1.y, vector1.x);
Run Code Online (Sandbox Code Playgroud)

并且您可能希望将其标准化为[0,2π)的范围:

if (angle < 0) { angle += 2 * M_PI; }
Run Code Online (Sandbox Code Playgroud)

或者到范围(-π,π):

if (angle > M_PI)        { angle -= 2 * M_PI; }
else if (angle <= -M_PI) { angle += 2 * M_PI; }
Run Code Online (Sandbox Code Playgroud)

  • 该解决方案需要 2 次调用 `atan2`,成本高昂,而此答案 /sf/answers/1504052371/ 只需要一次。 (3认同)
  • @ user3150201:这取决于你想要什么,因为矢量之间有两个角度. - 上面的方法给出一个角度a,如果你逆时针旋转vector1这个角度,那么结果就是vector2. (2认同)
  • @ user3150201:或者你想要向量之间的两个可能角度的**,即结果在0 ... Pi的范围内? (2认同)

ja7*_*a72 40

正确的方法是使用十字产品找到角度的正弦值,使用点积找到角度的余弦值,并将两者结合起来Atan2().

C#这是

public struct Vector2
{
    public double X, Y;

    /// <summary>
    /// Returns the angle between two vectos
    /// </summary>
    public static double GetAngle(Vector2 A, Vector2 B)
    {
        // |A·B| = |A| |B| COS(?)
        // |A×B| = |A| |B| SIN(?)

        return Math.Atan2(Cross(A,B), Dot(A,B));
    }

    public double Magnitude { get { return Math.Sqrt(Dot(this,this)); } }

    public static double Dot(Vector2 A, Vector2 B)
    {
        return A.X*B.X+A.Y*B.Y;
    }
    public static double Cross(Vector2 A, Vector2 B)
    {
        return A.X*B.Y-A.Y*B.X;
    }
}
class Program
{
    static void Main(string[] args)
    {
        Vector2 A=new Vector2() { X=5.45, Y=1.12};
        Vector2 B=new Vector2() { X=-3.86, Y=4.32 };

        double angle=Vector2.GetAngle(A, B) * 180/Math.PI;
        // angle = 120.16850967865749
    }
}
Run Code Online (Sandbox Code Playgroud)

请参阅GeoGebra上面的测试用例.

GeoGebra

  • 这是跨产品的非标准定义.交叉产品的更传统定义见http://en.wikipedia.org/wiki/Cross_product. (2认同)
  • @andand:请参见http://mathworld.wolfram.com/CrossProduct.html中的(8),(9)。据我所知,它通常被称为平面中两个向量的叉积。 (2认同)
  • 感谢您提及GeoGebra,这是一款非常棒的工具! (2认同)

Kla*_*aus 16

我认为这里发布了一个更好的公式:http: //www.mathworks.com/matlabcentral/answers/16243-angle-between-two-vectors-in-3d

angle = atan2(norm(cross(a,b)), dot(a,b))
Run Code Online (Sandbox Code Playgroud)

所以这个公式适用于2维或3维.对于2维,该公式简化为上述公式.

  • 我花了一段时间才意识到规范不规范化,但它是一个向量长度 (7认同)
  • 该公式丢弃 y 分量的符号,因为“norm(cross(a,b))”始终为正。 (2认同)

小智 7

没有人指出,如果你有一个单一的载体中,并希望找到从X轴的矢量的角度,就可以利用一个事实,即一个参数ATAN2()实际上是直线的斜率,或(增量Y/delta X).因此,如果您知道坡度,您可以执行以下操作:

给定:

A =您想要确定的矢量/线的角度(从X轴开始).

m =向量/线的带符号斜率.

然后:

A = atan2(m,1)

很有用!