сравнивая два угла - PullRequest
4 голосов
/ 23 мая 2010

Учитывая четыре точки на плоскости, A,B,X,Y, я хочу определить, какой из следующих двух углов меньше ∢ABX или ∢ABY.

Угол ∢ABX определяется как угол BX, когда AB переводится как лежащий на открытом сегменте (-∞,0]. Интуитивно, говоря «1010», я имею в виду угол, который вы получаете, поворачивая налево после посещения вершины B.

Я бы предпочел не использовать cos или sqrt, чтобы сохранить точность и минимизировать производительность (код будет работать во встроенной системе).

В случае, когда A=(-1,0),B=(0,0), я могу сравнить два угла ∢ABX и ∢ABY, вычислив скалярное произведение векторов X,Y и посмотреть его знак.

Что я могу сделать в этом случае:

  1. Определите, поворачивается ли ABX вправо или влево
  2. Если ABX поворачивает налево, проверьте, находятся ли Y и A на одной стороне линии на отрезке BX. Если они - ∢ABX меньше, чем ABY.
  3. Если ABX повернет направо, то Y и A на одной стороне BX означает, что ∢ABX больше ∢ABY.

Но мне это кажется слишком сложным.

Есть какой-нибудь более простой подход?

Ответы [ 6 ]

2 голосов
/ 23 мая 2010

Вот какой-то псевдокод. Не обнаруживает случай, когда оба угла одинаковы. Также не касается ориентации угла, например, предполагается, что все углы <= 180 градусов. </p>

v0 = A-B
v1 = X-B
v2 = Y-B

dot1 = dot(v0, v1)
dot2 = dot(v0, v2)

if(dot1 > 0)
  if(dot2 < 0)
    // ABX is smaller
  if(dot1 * dot1 / dot(v1,v1) > dot2 * dot2 / dot(v2, v2) )
    // ABX is smaller
  // ABY is smaller

if(dot2 > 0)
  // ABY is smaller
if(dot1 * dot1 / dot(v1,v1) > dot2 * dot2 / dot(v2,v2) )
  // ABY is smaller
// ABX is smaller

Обратите внимание, что большая часть этой мучительной боли исчезнет, ​​если вы позволите взять два квадратных корня.

1 голос
/ 24 мая 2010

Возможно, вы захотите проверить Рациональная тригонометрия .Идеи расстояния и угла заменяются квадрантом и разбросом, которые не включают sqrt и cos.Посмотрите на нижнюю часть этой веб-страницы, чтобы увидеть, как рассчитывается разброс между двумя строками.У субъекта есть собственный веб-сайт и даже канал на YouTube .

1 голос
/ 23 мая 2010

Центрируйте источник на B, выполнив

X = X - B
Y = Y - B
A = A - B

РЕДАКТИРОВАТЬ : вам также нужно нормализовать 3 вектора

A = A / |A|
X = X / |X|
Y = Y / |Y|

Найти два угла, выполнив

acos(A dot X)
acos(A dot Y)

===

Я не понимаю смысла потери точности.Вы просто сравниваете, никак не изменяя координаты точек ...

0 голосов
/ 23 мая 2010

Я не уверен, что вы можете уйти без использования sqrt. Простой:

AB = A-B/|A-B|
XB = X-B/|X-B|
YB = Y-B/|Y-B|

if(dot(XB,AB) > dot (YB,AB)){
 //<ABY is grater
}
else
{
...
}
0 голосов
/ 23 мая 2010

Используйте закон косинусов: a**2 + b**2 - 2*a*b*cos(phi) = c**2

где a = | ax |, b = | bx | (| by |), c = | ab | (| ay |) и phi - ваш угол ABX (ABY)

0 голосов
/ 23 мая 2010

Я бы предпочел не использовать cos или sqrt, чтобы сохранить точность.

Это не имеет никакого смысла.

Но мне это кажется слишком сложным.

Мне кажется, это совершенно неправильно.

Возьмите разницу между двумя векторами и посмотрите на знаки компонентов.

Вещь, с которой вы должны быть осторожны, это то, что означает «меньше». Эта идея не очень точна, как заявлено. Например, если одна точка A находится в квадранте 4 (x-компонент> 0 и y-компонент <0), а другая точка B находится в квадранте 1 (x-компонент> 0 и y-компонент> 0), что означает " меньше "значит? Угол вектора от начала координат до A находится между нулем и / pi; / 2; угол вектора от начала координат до B находится между 3 & pi; / 4 и 2 & pi ;. Какой из них "меньше"?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...