例如,GetAngle((0,0),(100,0),(100,100))= 90.如何找到3个2D点之间的角度。
答案 0 :(得分:9)
给定A,B和C点,你想要AB和AC之间的角度?首先计算向量AB和AC - 它只是B的坐标减去A的坐标,同样对于AC。取两个向量的dot product。这只是x坐标加上矢量y坐标的乘积。将此数字除以AB的长度,再按AC的长度除以。这个结果是两个向量之间角度的余弦,所以取arccos()就可以得到它。
答案 1 :(得分:7)
此处仅使用点积的问题在于它在0度或180度附近不稳定 - acos()的斜率接近+/- 1.0附近的无穷大,这将导致精度损失。
要解决此问题,您可以计算伪十字产品,并使用atan2(),如下所示:
// given A, B, C are 2D points:
BA= B - A; CA= C - A // vector subtraction, to get vector between points
dot= BA.x * CA.x + BA.y * CA.y
pcross= BA.x * CA.y - BA.y * CA.x
angle= atan2(pcross, dot) // this should be the angle BAC, in radians
除非角度的一条腿长度为零,否则这应该是数值上的。
请注意,这也会为您提供签名的角度,具体取决于BAC是顺时针还是逆时针; acos()方法总会给你一个正值。当然,如果你只想要一个正角度,你可以采用abs(angle)
; atan2()方法仍然会更强大,可能更快。
答案 2 :(得分:1)
使用点积:
(a,b,c) dot (d,e,f) = ad + be + bf
。
A dot B = length(A)*length(B)* cos(theta)
theta = arccos((A dot B)/(length(A)*length(B))
是向量A和B之间的角度。
答案 3 :(得分:0)
如果您具备线性代数的基本知识,这很容易。
向量v(在线性代数意义上,而不是std :: vector;))是一个元组v =(x,y,z)。
范数是向量| v |的长度= sqrt(x x + y y + z * z)
两个向量v1 =(x1,y1,z1)和v2 =(x2,y2,z2)的内积为v1·v2 = x1 * x2 + y1 * y2 + z1 * z2
向量v1和v2的角度是a = acos(v1·v2 /(| v1 | * | v2 |))