khusamov
@khusamov
ReactJS, NodeJS, TypeScript, Sencha ExtJS

Как составить правильную формулу расчета угла между векторами?

Здравствуйте! Проблема такая. У меня есть формула расчета угла между векторами. Она стандартная:

cosf.gif

И вот есть два вектора, угол между которыми никак не вычислить, так как правая часть уравнения меньше -1. Вот эти вектора:

var x1 = -0.045797169475341334, y1 = -0.9989507591808752;
var x2 = 0.04579716947534099, y2 = 0.9989507591808753;


В итоге, выражение:

(x1 * x2 + y1 * y2) / Math.sqrt(Math.pow(x1, 2) + Math.pow(y1, 2)) * Math.sqrt(Math.pow(x2, 2) + Math.pow(y2, 2))


дает результат: -1.0000000000000002

И если взять арккосинус этого числа, то будет NaN, что и понятно, так как он определен на промежутке от -1 до 1.

Как мне скорректировать формулу, чтобы этой ошибки не было?
  • Вопрос задан
  • 875 просмотров
Решения вопроса 3
angru
@angru
var d = res < 0 ? Math.max(res, -1.0) : Math.min(res, 1.0);
Ответ написан
khusamov
@khusamov Автор вопроса
ReactJS, NodeJS, TypeScript, Sencha ExtJS
@Nc_Soft
Сухроб Хусамов: можно еще точность уменьшить (0.045797169475341334*0.04579716947534099 + 0.9989507591808752*0.9989507591808753).toFixed(6)

@GreatRash
Сухроб Хусамов: Там https://learn.javascript.ru/number#%D0%BD%D0%B5%D1... и решение написано - округлять результат до десятого знака после запятой (если нужна такая точность).

@andy.37 ru.stackoverflow.com/users/192530/andy-37

Пользуемся функцией atan2

phi = Math.atan2(y2, x2) - Math.atan2(y1, x1);
При необходимости, приводим полученный угол в нужный диапазон (0-180град или -90 - +90)

Оба алгоритма выдадут ошибку при x1=y1=0 или x2=y2=0, о чем написано выше. Вариант с atan2, имхо предпочтительней, т.к., например при x1=y1=1e+10, x2=y2=1e-10 точность вычислений по первому варианту будет околонулевой (e10 взято просто для примера, м.б. нужно существенно больше).

Математические функции указаны для Java, для .NET названия содержат заглавную букву: Math.Sqrt, Math.Atan2 и т. д.

Источник:
ru.stackoverflow.com/questions/470657/%D0%9A%D0%B0...
Ответ написан
Комментировать
@kstyle
найдите косинус по вашей формуле. а дальше если |cos fi - 1|<=0.000001 то считаем угол 180 или 0.
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
@southsoutheast
Мне интересно.
у вас модуль в верхней части пропущен.
Ответ написан
@GreatRash
Вы неверно считаете.

var dot_product = x1 * y1 + x2 * y2;
var length_1 = Math.sqrt(x1 * x1 + y1 * y1);
var length_2 = Math.sqrt(x2 * x2 + y2 * y2);

var cos_a = dot_product / (length_1 * length_2);
Ответ написан
@Nc_Soft
Еще вы неправильно считаете
(x1 * x2 + y1 * y2) / Math.sqrt(Math.pow(x1, 2) + Math.pow(y1, 2)) * Math.sqrt(Math.pow(x2, 2) + Math.pow(y2, 2))

Должно быть
(x1 * x2 + y1 * y2) / Math.sqrt(Math.pow(x1, 2) + Math.pow(y1, 2)) / Math.sqrt(Math.pow(x2, 2) + Math.pow(y2, 2))
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы