Не используйте acos, используйте atan2 .Чтобы acos работал, вы должны нормализовать разницу и по-разному обрабатывать угол> pi.С atan2 вы просто задаете разницу координат y, x, а остальное корректно обрабатывается.
РЕДАКТИРОВАТЬ
Вы искали угол между векторами, а не аргумент вектора разности, мой плохой.Нам просто нужно изменить способ обработки ошибок в расчетах.С некоторым псевдокодом:
function angle_between(ax, ay, bx, by) {
var al = ax*ax+ay*ay;
var bl = bx*bx+by*by;
var dot = (ax*bx+ay*by)/Math.sqrt(al2*bl2);
if (dot >= 1) return 0;
if (dot <= -1) return Math.PI;
return Math.acos(dot);
}
EDIT2
Хорошо, давайте посмотрим на решение atan2 тоже.Как отметил @njuffa, atan2 все еще можно использовать для вычисления угла между двумя векторами.Еще один квадратный корень, что хорошо.Это также дает нам угол со знаком, что даже лучше для некоторых приложений.
function signed_angle_between(ax, ay, bx, by) {
var dot = ax*bx + ay*by;
var cross = ax*by - ay*bx;
return Math.atan2(cross, dot);
}
console.log(signed_angle_between(3, 4, 30, 40));
console.log(signed_angle_between(2, 5, -50, 20));
console.log(signed_angle_between(2, 5, 50, -20));
console.log(signed_angle_between(1, 1, -1, -1));