这里仅使用点积的问题在于它在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
Run Code Online (Sandbox Code Playgroud)
除非角度的一条腿长度为零,否则这应该是数值上稳健的.
请注意,这也会给你一个签字的角度,这取决于是否BAC那张顺时针或逆时针方向; acos()方法总会给你一个正值.当然,如果你只想要一个正角度,你可以采取abs(angle); atan2()方法仍然会更强大,并且可能更快.