Краткий ответ: Теоретически это не имеет значения. Практически: измерить
Длинный ответ:
Соглашаясь с тем, что об обратных тригонометрических функциях не может быть и речи, давайте сравним наиболее эффективные способы вычисления последних двух вариантов.
Вычисление их перекрестного произведения
Поскольку вы допускаете, чтобы векторы были почти параллельными, вам необходимо вычислить
crossx := uy * vz + uz * vy;
crossy := ...;
crossz := ...;
crossNorm = crossx * crossx + crossy * crossy + crossz * crossz;
, который включает в себя 9 умножений и 5 сложений. Если векторы (почти) параллельны, тогда crossNorm
должен быть (почти) нулем.
Однако, как правильно заметил Baum mit Augen , достаточно проверить, что crossx
, crossy
и crossz
почти равны нулю, уменьшив это до 6 умножений и 3 сложений, при за счет еще двух сравнений. Что является более эффективным, зависит от деталей вашего языка и определения «почти» равных & ndash; например если «почти равно» означает, что fabs(...) < 1E-6
может стоить сделать это только один раз.
Расчет скалярного произведения
Скалярное произведение
scalar = ux * vx + uy * vy + uz * vz;
Если векторы (почти) параллельны, тогда
scalar * scalar
должно (почти) равняться
(ux * ux + uy * uy + uz * uz) * (vx * vx + vy * vy + vz * vz).
Это сводится к 10 умножениям и 6 сложениям.
Нормализация их и проверка, является ли их скалярное произведение единицей.
Это только вышеприведенный расчет, но с двумя дополнительными double
делениями. Это не добавляет никакой ценности, фактически может привести к проблемам с округлением.
Заключение
Количество двойных операций практически одинаково для обоих вариантов. Если вы действительно хотите знать, вы можете сравнить сборку https://godbolt.org/z/nJ9CXl, но разница будет минимальной для всех практических целей. На самом деле, если считать только «дорогие» инструкции (mulsd
, addsd
, subsd
) и сравнения (ucomisd
), оба варианта имеют пять из них. Однако, опять же, если вы должны точно знать , измерьте его!