Проблема с использованием только точечного произведения здесь заключается в том, что он нестабилен около 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
Это должно быть численно устойчиво, если только одна из ножек угла не имеет нулевой длины.
Обратите внимание, что это также даст вам угол со знаком , в зависимости от того, идет ли ВАС по часовой стрелке или против часовой стрелки; метод acos () всегда даст вам положительное значение. Конечно, если вам нужен только положительный угол, вы можете взять abs(angle)
; метод atan2 () все еще будет более устойчивым и, вероятно, быстрее.