Полагаю, что A
и B
являются нормализованными векторами, и поэтому вы ожидаете, что dot(A, B)
будет между -1
и 1
. С математикой с плавающей точкой это не обязательно верно. |dot(A, B)|
может быть немного больше, чем 1
. Бьюсь об заклад, если вы напечатаете его с большей точностью, вы увидите, что ваше значение немного меньше, чем -1
.
Итак, вам нужно зажать dot(A, B)
между -1
и 1
. Или, что еще лучше, вызывайте acos()
только, если ввод находится между -1
и 1
:
double safe_acos(double value) {
if (value<=-1.0) {
return <pi>;
} else if (value>=1.0) {
return 0;
} else {
return acos(value);
}
}
Это может быть немного быстрее, так как вы избегаете вызова acos()
для значений вне пределов.
Примечание. Если вы занимаетесь трехмерной математикой, существует большая вероятность того, что вы вообще можете не звонить acos()
. Используя тригонометрические тождества, обычно мы можем заменить это чем-то более быстрым и более точным решением.