我试图找出两个2D矢量之间的角度(以度为单位)。我知道我需要使用trig,但我对它不太好。这就是我想要解决的问题(Y轴向下增加): alt text 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;
}
这些是我的结果(提供恒定位置时常数,但当我改变位置时,角度改变,我找不到两个角度之间的任何联系):
位置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
编辑:谢谢所有回答并帮助我弄清楚错误的人!对不起,标题和问题令人困惑。
答案 0 :(得分:14)
首先必须了解如何计算两个向量之间的角度,其中有几个。我会告诉你我认为最简单的事情。
v1x * v2x + v1y * v2y
有了这些信息,请采用以下定义:
dot(v1, v2) = norm(v1) * norm(v2) * cos(angle(v1, v2))
现在,您解决angle(v1, v2)
:
angle(v1, v2) = acos( dot(v1, v2) / (norm(v1) * norm(v2)) )
最后,根据开头给出的定义,最后得到:
angle(v1, v2) = acos( (v1x * v2x + v1y * v2y) / (sqrt(v1x^2+v1y^2) * sqrt(v2x^2+v2y^2)) )
同样,有很多方法可以做到这一点,但我喜欢这个,因为它给出了给定矢量给定角度和范数或角度的点积。
答案是弧度,但你知道pi弧度(即3.14弧度)是180度,所以你只需乘以转换因子180 / pi。
答案 1 :(得分: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;
}
感谢大家帮助我解决这个问题,并帮助我理解我在做什么! :)
答案 2 :(得分:5)
不要将参数的绝对值设为atan2
。 atan2
的全部意义在于它使用其参数的符号来确定角度所在的qaudrant。通过取绝对值,您强制atan2
仅返回0到pi之间的值/ 2而不是-pi到pi。
答案 3 :(得分:2)
看起来Niall想出来了,但无论如何我会完成我的解释。除了解释解决方案的工作原理外,我的解决方案还有两个优点:
atan2()
返回相对于正X轴的逆时针角度。 Niall正在寻找相对于正Y轴的顺时针角度(在由两个点和正Y轴形成的矢量之间)。
以下功能改编自我的小行星游戏,我想计算船舶/速度矢量的方向“指向:”
// Calculate angle between vector from (x1,y1) to (x2,y2) & +Y axis in degrees.
// Essentially gives a compass reading, where N is 0 degrees and E is 90 degrees.
double bearing(double x1, double y1, double x2, double y2)
{
// x and y args to atan2() swapped to rotate resulting angle 90 degrees
// (Thus angle in respect to +Y axis instead of +X axis)
double angle = Math.toDegrees(atan2(x1 - x2, y2 - y1));
// Ensure result is in interval [0, 360)
// Subtract because positive degree angles go clockwise
return (360 - angle) % 360;
}
答案 4 :(得分:1)
我相信两个向量之间角度的等式应该更像:
toDegrees(acos((x*x1+y*y1)/(sqrt(x*x+y*y)*sqrt(x1*x1+y1*y1))))
上面的等式将计算矢量p1-p2与通过从点p2到矢量p1的正交延伸而产生的线之间的角度。
两个矢量V1和V2的点积等于| V1 | * | V2 | cos(θ)。因此,θ等于acos((V1点V2)/(| V1 | | V2 |))。 V1点V2是V1.x V2.x + V1.y V2.y。 V的大小(即| V |)是pathogorean定理... sqrt(V.x ^ 2 + V.y ^ 2)
答案 5 :(得分:0)
应该是:
atan( abs(x1 - x)/abs(y1 - y) )
abs
代表绝对值(避免负值)
答案 6 :(得分:0)
res * =(360.0 /(2.0 * Math.PI));
答案 7 :(得分:0)
我的第一个猜测是使用atan(y / x)计算每个矢量与轴的角度,然后减去那些天使并取绝对值,即:
abs(atan(y / x) - atan(y1 / x1))
答案 8 :(得分:0)
第二个向量相对于第一个= atan2(y2,x2) - atan2(y1,x1)
的角度。
http://www.euclideanspace.com/maths/algebra/vectors/angleBetween/index.htm