Чисельно стійкий спосіб обчислення кутів між векторами


14

При застосуванні класичної формули кута між двома векторами:

α=arccosv1v2v1v2

виявляється, що при дуже малих / гострих кутах втрачається точність, і результат не є точним. Як пояснено у цій відповіді про переповнення стека , одним із варіантів є використання арктангенту:

α=arctan2(v1×v2,v1v2)

І це справді дає кращі результати. Однак мені цікаво, чи це дало б погані результати для кутів, дуже близьких до π/2 . Це так? Якщо так, чи існує якась формула для точного обчислення кутів, не перевіряючи на допуск всередині ifгілки?


1
Це залежатиме від реалізації функції зворотного дотику двох параметрів. Повільні, стабільні версії умовно перемикаються між роботою з x / y та y / x, щоб підтримувати точність, тоді як швидкі просто приклеюють речі у потрібний квадрант і, таким чином, не є більш точним, ніж версія одного параметра.
оригімбо

Вам слід визначити "втрата точності": припустимо, правильною відповіддю є α і ви отримаєте замість α+Δ . Вам достатньо Δα або Δπ ?
Стефано М

У цьому випадку правильною відповіддю було і я отримав , обидва . α 10 81αα1081
astrojuanlu

Відповіді:


18

( Я вже перевіряв цей підхід і пам'ятаю, що він працював правильно, але я не перевіряв його спеціально для цього питання. )

Наскільки я можу сказати, обидва і може постраждати від катастрофічного скасування, якщо вони майже паралельні / перпендикулярні - atan2 не може дати точну точність, якщо будь-який вхід вимкнено.v 1v 2v1×v2v1v2

Почніть з переформулювання задачі як знаходження кута трикутника зі сторонами довжини,і(всі вони точно обчислені в арифметиці з плаваючою точкою). Існує добре відомий варіант формули Герона завдяки Кахану ( Площа прорахунку та кути голкоподібного трикутника ), що дозволяє обчислити площу та кут (між і ) трикутника, визначеними його сторонами, і робити це стабільно чисельно. Оскільки зменшення цієї підпроблеми також точне, такий підхід повинен працювати для довільних даних.b = | v 2 | c = | v 1 - v 2 | a ba=|v1|b=|v2|c=|v1v2|ab

Цитуючи цей документ (див. П. 3), припускаючи, що , Усі круглі дужки тут розміщуються обережно, і вони мають значення; якщо ви знайдете квадратний корінь від’ємного числа, довжина вхідної сторони не є бічними довжинами трикутника.μ = { c - ( a - b ) , якщо  b c 0 , b - ( a - c ) , якщо  c > b 0 , недійсний трикутник , інакше a n g l e = 2 арктану ( ab

μ={c(ab),if bc0,b(ac),if c>b0,invalid triangle,otherwise
angle=2arctan(((ab)+c)μ(a+(b+c))((ac)+b))

У статті Кахана є пояснення того, як це працює, включаючи приклади значень, для яких інші формули виходять з ладу. Ваша перша формула для є на сторінці 4.C αC

Основна причина, за якою я пропоную формулу Герона Кахана, полягає в тому, що це робить дуже приємним примітивом - багато потенційно складних запитань з площинної геометрії можна звести до пошуку площі / кута довільного трикутника, тож якщо ви можете звести свою проблему до цього, є приємна стабільна формула для цього, і немає необхідності придумувати щось самостійно.

Змінити Після коментаря Стефано, я зробив графік відносної помилки для , ( код ). Два рядки є відносними помилками для та , йдуть уздовж горизонтальної осі. Здається, що це працює. v 2 = ( cos θ , sin θ ) θ = ϵ θ = π / 2 - ϵ ϵv1=(1,0)v2=(cosθ,sinθ)θ=ϵθ=π/2ϵϵвведіть тут опис зображення


Дякуємо за посилання та відповідь! На жаль, друга формула, яку я написав, не міститься в статті. З іншого боку, цей метод може отримати трохи складний характер, оскільки вимагає проекції в 2D.
astrojuanlu

2
@astrojuanlu Тут немає проекції на 2d: якими б не були два 3d вектори, вони визначають один (плоский) трикутник між ними - потрібно лише знати його бічні довжини.
Кирило

Ви маєте рацію, мій коментар не має сенсу. Я думав про координати замість довжин. Знову дякую!
astrojuanlu

2
@astrojuanlu Ще одне, що я хочу зазначити: схоже, існує офіційний доказ того, що формула області є точною у тому, як обчислити площу трикутника: формальне повторне відвідування , Сільві Болдо , використовуючи Flocq.
Кирило

Відмінна відповідь, але я заперечую, що ви завжди можете точно обчислити в арифметиці з плаваючою комою. Насправді, якщо то в обчисленні компонентів трапляються катастрофічні скасування . c < ϵ min ( a , b ) ( v 1 - v 2 )cc<ϵmin(a,b)(v1v2)
Стефано М

7

Ефективна відповідь на це питання не надто дивно, але в іншій замітці Велвеля Кахана :

α=2arctan(v1v1+v2v2,v1v1v2v2)

де я використовую як кут, зроблений з горизонтальною віссю. (Можливо, вам доведеться перегорнути порядок аргументів на деяких мовах.)( х , у )arctan(x,y)(x,y)

(Я дав Mathematica демонстрацію формули Каган в тут .)


Ви маєте на увазі ? arctan2
astrojuanlu

1
Я звик просто зображати двоаргументний арктангент як , так. Такою мовою, як FORTRAN, був би еквівалент . arctan(x,y)ATAN2(Y, X)
JM
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.