Абсолютный угол между линиями с использованием обратного косинуса - PullRequest
4 голосов
/ 04 августа 2011

Я хочу вычислить угол между двумя линиями, образованными тремя точками (одна из точек является точкой пересечения двух линий), используя функцию обратного косинуса следующим образом:

CGFloat a = initialPosition.x - origin.x;
CGFloat b = initialPosition.y - origin.y;
CGFloat c = currentPosition.x - origin.x;
CGFloat d = currentPosition.y - origin.y;
CGFloat angle = (180/M_PI) * acosf(((a*c) + (b*d)) / ((sqrt(a*a + b*b)) * (sqrt(c*c + d*d))));

К сожалению, acosfвозвращает значение только от 0 до pi.Как найти значение между 0 и 2 * пи (например, против часовой стрелки)?

Ответы [ 2 ]

7 голосов
/ 04 августа 2011

Я не знаю, какой язык вы используете, но обычно есть функция atan2, которая дает вам значение из полных 360 градусов.в этом случае вам нужно использовать его дважды, а затем добавить немного дополнительной логики.

некоторый псевдокод поможет разобраться:

initialAngle = atan2(initialPosition.y - origin.y, initialPosition.x - origin.x)
currentAngle = atan2(currentPosition.y - origin.y, currentPosition.x - origin.x)
# angle is measured from x axis anti-clock, so lets find the value starting from
# initial and rotating anti-clock to current, as a positive number
# so we want current to be larger than initial
if (currentAngle < initialAngle) {currentAngle += 2 pi}
# and then we can subtract
return currentAngle - initialAngle

я знаю, что это не использует acos, ноэто многозначное значение, поэтому для этого нужно использовать много логики о признаках различий, которые подвержены ошибкам.atan2 - это то, что вы хотите.

2 голосов
/ 05 августа 2011

нашел простое решение ... Это из математики средней школы!Сначала составьте уравнение для линии, сделанной из начала координат и начальной позиции вида y = mx+c.Точка, лежащая по обе стороны от этой линии, будет удовлетворять y < mx+c или y > mx+c, в зависимости от того, где она находится.Если вы находите углы в направлении по часовой стрелке или против часовой стрелки, сделайте следующую проверку:

currentPosition.y < (currentPosition.x *(initialPosition.y - origin.y) + (initialPosition .x * origin.y - initialPosition.y * origin.x))  / (initialPosition.x - origin.x)

Если вышеприведенное условие выполнено, то линия, образованная из origin и currentPosition, делает угол менее 180 градусов (впо часовой стрелке) с линией, образованной из origin и initialPosition.В противном случае он составляет угол более 180 градусов по часовой стрелке и менее 180 градусов против часовой стрелки ... и так далее.В зависимости от требования, конечный угол равен либо (angle returned by acos), либо (360 - (angle returned by acos)).

.
...