При применении классической формулы для угла между двумя векторами:
обнаруживается, что при очень малых / острых углах наблюдается потеря точности, и результат не является точным. Как объясняется в ответе на переполнение стека , одно из решений - использовать вместо этого арктангенс:
И это действительно дает лучшие результаты. Тем не менее, мне интересно, даст ли это плохие результаты для углов, очень близких к . Это так? Если да, то есть ли какая-нибудь формула для точного вычисления углов без проверки допуска внутри if
ветви?
algorithms
precision
numerical-limitations
astrojuanlu
источник
источник
Ответы:
( Я проверял этот подход раньше, и я помню, что он работал правильно, но я не проверял его специально для этого вопроса. )
Насколько я могу судить, оба и может пострадать от катастрофической отмены, если они почти параллельны / перпендикулярны - atan2 не может дать вам хорошую точность, если любой из входов отключен.∥v1×v2∥ v1⋅v2
Начните с переформулировки задачи как нахождения угла треугольника с длинами сторон,и(все они точно рассчитаны в арифметике с плавающей запятой). Существует хорошо известный вариант формулы Герона из-за Кахана ( Miscalculation Area and Angles of Needle-подобные треугольники ), который позволяет вычислять площадь и угол (между и ) треугольника, заданного длиной его стороны, и делать это численно стабильно. Поскольку приведение к этой подзадаче также является точным, этот подход должен работать для произвольных входных данных.a=|v1| b=|v2| c=|v1−v2| a b
Цитирование из этой статьи (см. Стр.3), предполагая, что , Все круглые скобки здесь размещены аккуратно, и они имеют значение; если вы обнаружите, что берете квадратный корень из отрицательного числа, длина входной стороны не равна длине стороны треугольника.a≥b
Существует объяснение того, как это работает, включая примеры значений, для которых другие формулы не работают, в статье Кахана. Ваша первая формула для - это на странице 4.α C′′
Основная причина, по которой я предлагаю формулу Керона Кахана, состоит в том, что она делает очень хороший примитив - множество потенциально хитрых вопросов плоской геометрии может быть сведено к нахождению площади / угла произвольного треугольника, так что если вы можете свести свою проблему к этому, хорошая стабильная формула для этого, и нет необходимости придумывать что-то самостоятельно.
Редактировать После комментария Стефано я сделал график относительной ошибки для , ( код ). Две линии - это относительные ошибки для и , идущих вдоль горизонтальной оси. Кажется, это работает.v1=(1,0) v2=(cosθ,sinθ) θ=ϵ θ=π/2−ϵ ϵ
источник
Эффективный ответ на этот вопрос, что неудивительно, в другой заметке Велвела Кахана :
где я использую в качестве угла с горизонтальной осью. (Возможно, вам придется изменить порядок аргументов в некоторых языках.)arctan(x,y) (x,y)
(Я дал Mathematica демонстрацию формулы Кахана здесь .)
источник
ATAN2(Y, X)