Допустим, у вас есть это:
P1 = (x=2, y=50)
P2 = (x=9, y=40)
P3 = (x=5, y=20)
Предположим, что P1
это центральная точка круга. Всегда одно и то же. Мне нужен угол, образованный P2
и P3
, или, другими словами, угол, который находится рядом P1
. Внутренний угол, если быть точным. Это всегда будет острый угол, поэтому меньше -90 градусов.
Я подумал: «Боже, это же простая геометрическая математика». Но я искал формулу около 6 часов и обнаружил, что люди говорят только о сложных вещах НАСА, таких как arccos и векторные скалярные произведения. Голова словно в холодильнике.
Некоторые математические гуру думают, что это простая проблема? Я не думаю, что язык программирования имеет здесь значение, но для тех, кто думает, что это имеет значение: java и objective-c. Мне он нужен для обоих, но я не пометил его для них.
Это становится очень просто, если вы думаете, что это два вектора, один от точки P1 до P2, а другой от P1 до P3.
так:
a = (p1.x - p2.x, p1.y - p2.y)
b = (p1.x - p3.x, p1.y - p3.y)
Затем вы можете инвертировать формулу скалярного произведения:
чтобы получить угол:
Помните, что это просто означает: a1 * b1 + a2 * b2 (здесь всего 2 измерения ...)
источник
Лучший способ справиться с вычислением угла - использовать
atan2(y, x)
то, что заданная точкаx, y
возвращает угол от этой точки иX+
ось по отношению к началу координат.Учитывая, что вычисление
то есть вы в основном переводите две точки на
-P1
(другими словами, вы переводите все, чтоP1
попадает в начало координат), а затем вы рассматриваете разницу абсолютных угловP3
иP2
.Преимущество
atan2
заключается в том, что представлен полный круг (вы можете получить любое число от -π до π), где вместо этогоacos
вам нужно обрабатывать несколько случаев в зависимости от знаков для вычисления правильного результата.Единственная особенность для
atan2
is(0, 0)
... означает, что обаP2
иP3
должны отличаться отP1
as в этом случае не имеет смысла говорить об угле.источник
atan2
это именно то, что нужно для этой проблемы, но похоже, что большинство людей, которые задаются этим вопросом, просто не могут прочитать или не могут понять, почемуacos
решения на основе плохой. К счастью для меня, я оставил фазу «кто-то не прав в Интернете» ( xkcd.com/386 ) много лет назад, и я не собираюсь начинать борьбу за защиту очевидного :-)Приведу пример на JavaScript, я много боролся с этим:
Бонус: пример с HTML5-канвой
источник
sqrt
и возводя в квадрат. См. Мой ответ здесь (написанный на Ruby) или в этой обновленной демонстрации (JavaScript).По сути, у вас есть два вектора: один от P1 до P2, а другой от P1 до P3. Итак, все, что вам нужно, это формула для вычисления угла между двумя векторами.
Посмотрите здесь хорошее объяснение и формулу.
источник
Если вы думаете о P1 как о центре круга, вы думаете слишком сложно. У вас простой треугольник, поэтому ваша задача решается с помощью закона косинусов . Нет необходимости в преобразовании полярных координат или в чем-то подобном. Скажем, расстояния P1-P2 = A, P2-P3 = B и P3-P1 = C:
Все, что вам нужно сделать, это вычислить длину расстояний A, B и C. Их легко получить из координат x и y ваших точек и теоремы Пифагора.
источник
P1-P2 = A
не следует читать как «Чтобы вычислить A, вычтите P2 из P1», а как «Я определяю A как расстояние от P1 до P2», которое затем можно вычислить с использованием второго уравнения. Я просто хотел дать сокращенное обозначение расстояний, чтобы уравнения были более удобочитаемыми.Недавно я столкнулся с подобной проблемой, только мне нужно было различать положительный и отрицательный углы. Если это кому-то пригодится, я рекомендую фрагмент кода, который я взял из этого списка рассылки, об обнаружении поворота по событию касания для Android:
источник
Очень простое геометрическое решение с пояснением
Несколько дней назад я столкнулся с той же проблемой и вынужден был сидеть с учебником по математике. Я решил проблему, объединив и упростив некоторые основные формулы.
Давайте рассмотрим эту цифру -
Мы хотим знать ϴ , поэтому нам нужно сначала узнать α и β . Теперь для любой прямой -
Пусть- A = (ax, ay) , B = (bx, by) и O = (ox, oy) . Итак, для линии OA -
Таким же образом для линии OB -
Теперь нам нужно
ϴ = β - α
. В тригонометрии у нас есть формула:После замены значения
tan α
(из уравнения-2) иtan b
(из уравнения-3) в уравнении-4 и применения упрощения мы получаем:Так,
Вот и все!
Теперь возьмем следующий рисунок -
Этот метод C # или Java вычисляет угол ( ϴ ) -
источник
В Objective-C это можно сделать с помощью
Или читайте подробнее здесь
источник
Вы упомянули угол со знаком (-90). Во многих приложениях углы могут иметь знаки (положительные и отрицательные, см. Http://en.wikipedia.org/wiki/Angle ). Если точки (скажем) P2 (1,0), P1 (0,0), P3 (0,1), то угол P3-P1-P2 условно положительный (PI / 2), тогда как угол P2-P1- P3 отрицательный. Использование длин сторон не приведет к различию между + и -, поэтому, если это имеет значение, вам нужно будет использовать векторы или функцию, такую как Math.atan2 (a, b).
Углы также могут выходить за пределы 2 * PI, и хотя это не имеет отношения к текущему вопросу, было достаточно важно, чтобы я написал свой собственный класс Angle (также чтобы убедиться, что градусы и радианы не перепутались). Вопрос о том, меньше ли angle1, чем angle2, во многом зависит от того, как определяются углы. Также может быть важно решить, будет ли линия (-1,0) (0,0) (1,0) представлена как Math.PI или -Math.PI.
источник
Недавно у меня тоже возникла такая же проблема ... В Delphi это очень похоже на Objective-C.
источник
Вот метод C # для возврата угла (0-360) против часовой стрелки от горизонтали для точки на окружности.
Привет, Пол
источник
источник
есть простой ответ на этот вопрос, используя математику средней школы.
Допустим, у вас 3 очка
Чтобы получить угол от точки A до B
angle = atan2(A.x - B.x, B.y - A.y)
Чтобы получить угол от точки B до C
angle2 = atan2(B.x - C.x, C.y - B.y)
Я просто использовал этот код в недавнем проекте, который я сделал, измените B на P1 .. вы можете также удалить "180 +", если хотите
источник
ну, другие ответы, похоже, охватывают все необходимое, поэтому я хотел бы просто добавить это, если вы используете JMonkeyEngine:
Vector3f.angleBetween(otherVector)
так как это то, что я сюда искал :)
источник
}
источник