如何从垂直方向计算矢量的角度?

Nia*_*all 10 language-agnostic algorithm math trigonometry

我试图找出两个2D矢量之间的角度(以度为单位).我知道我需要使用trig,但我对它不太好.这就是我想要解决的问题(Y轴向下增加): 替代文字http://i38.tinypic.com/2dcefch.png

我正在尝试使用此代码,但它根本不起作用(由于某种原因计算随机角度):

private float calcAngle(float x, float y, float x1, float y1)
{
    float _angle = (float)Math.toDegrees(Math.atan2(Math.abs(x1-x), Math.abs(y1-y)));
    Log.d("Angle","Angle: "+_angle+" x: "+x+" y: "+y+" x1: "+x1+" y1: "+y1);
    return _angle;
}
Run Code Online (Sandbox Code Playgroud)

这些是我的结果(提供恒定位置时常数,但是当我改变位置时,角度改变,我找不到两个角度之间的任何连接):

位置1:x:100 y:100 x1:50 y1:50角度:45

位置2:x:92 y:85 x1:24 y1:16角度:44.58

位置3:x:44 y:16 x1:106 y1:132角度:28.12

编辑:谢谢所有回答并帮助我弄清楚错误的人!对不起,标题和问题令人困惑.

Esc*_*alo 15

首先,您必须了解如何计算两个向量之间的角度,并且有几个向量.我会告诉你我认为最简单的.

  1. 给定v1v2,它们的点积为:v1x * v2x + v1y * v2y
  2. 向量v的范数由下式给出:sqtr(vx ^ 2 + vy ^ 2)

有了这些信息,请采用以下定义:

dot(v1, v2) = norm(v1) * norm(v2) * cos(angle(v1, v2))
Run Code Online (Sandbox Code Playgroud)

现在,你解决了angle(v1, v2):

angle(v1, v2) = acos( dot(v1, v2) / (norm(v1) * norm(v2)) )
Run Code Online (Sandbox Code Playgroud)

最后,根据开头给出的定义,最后得到:

angle(v1, v2) = acos( (v1x * v2x + v1y * v2y) / (sqrt(v1x^2+v1y^2) * sqrt(v2x^2+v2y^2)) )
Run Code Online (Sandbox Code Playgroud)

同样,有很多方法可以做到这一点,但我喜欢这个,因为它给出了给定矢量给定角度和范数或角度的点积.

答案将是弧度,但你知道pi弧度(即3.14弧度)是180度,所以你只需乘以转换因子180/pi.


Nia*_*all 13

啊哈!结果我只需要翻转我的角度并使用atan2.这是我的最终代码:

private float calcAngle(float x, float y, float x1, float y1)
{
    float _angle = (float)Math.toDegrees(Math.atan2(x1-x, y-y1));
    return _angle;
}
Run Code Online (Sandbox Code Playgroud)

感谢大家帮助我解决这个问题,也帮助我理解我在做什么!:)


Tro*_*our 5

不要取参数的绝对值atan2.整个观点atan2是,它使用其参数的符号来计算角度所在的qaudrant.通过取绝对值,您强制atan2只返回介于0和pi/2之间的值,而不是-pi到pi.