Использование atan2 для нахождения угла между двумя векторами
Я понимаю, что:
atan2(vector.y, vector.x)
= угол между вектором и осью X.
Но я хотел знать, как получить угол между двумя векторами, используя atan2. Поэтому я наткнулся на это решение:
atan2(vector1.y - vector2.y, vector1.x - vector2.x)
Мой вопрос очень прост:
Получают ли две следующие формулы одинаковое число?
-
atan2(vector1.y - vector2.y, vector1.x - vector2.x)
-
atan2(vector2.y - vector1.y, vector2.x - vector1.x)
Если нет: Как я узнаю, какой вектор приходит первым в вычитаниях?
Спасибо
Ответы
Ответ 1
atan2(vector1.y - vector2.y, vector1.x - vector2.x)
это угол между вектором разности (соединяющим vector2 и vector1) и осью x, что, вероятно, не то, что вы имели в виду.
(Направленный) угол от вектора 1 до вектора 2 может быть вычислен как
angle = atan2(vector2.y, vector2.x) - atan2(vector1.y, vector1.x);
и вы можете нормализовать его до диапазона [0, 2 π):
if (angle < 0) { angle += 2 * M_PI; }
или в диапазон (-π, π]:
if (angle > M_PI) { angle -= 2 * M_PI; }
else if (angle <= -M_PI) { angle += 2 * M_PI; }
Ответ 2
Правильный способ сделать это - найти синус угла с использованием поперечного произведения и косинус угла с использованием точечного произведения и объединить два с функцией Atan2()
.
В C#
это
public struct Vector2
{
public double X, Y;
/// <summary>
/// Returns the angle between two vectos
/// </summary>
public static double GetAngle(Vector2 A, Vector2 B)
{
// |A·B| = |A| |B| COS(θ)
// |A×B| = |A| |B| SIN(θ)
return Math.Atan2(Cross(A,B), Dot(A,B));
}
public double Magnitude { get { return Math.Sqrt(Dot(this,this)); } }
public static double Dot(Vector2 A, Vector2 B)
{
return A.X*B.X+A.Y*B.Y;
}
public static double Cross(Vector2 A, Vector2 B)
{
return A.X*B.Y-A.Y*B.X;
}
}
class Program
{
static void Main(string[] args)
{
Vector2 A=new Vector2() { X=5.45, Y=1.12};
Vector2 B=new Vector2() { X=-3.86, Y=4.32 };
double angle=Vector2.GetAngle(A, B) * 180/Math.PI;
// angle = 120.16850967865749
}
}
См. тестовый пример выше в GeoGebra.
![GeoGebra]()
Ответ 3
Я думаю, что лучшая формула была опубликована здесь:
http://www.mathworks.com/matlabcentral/answers/16243-angle-between-two-vectors-in-3d
angle = atan2(norm(cross(a,b)), dot(a,b))
Таким образом, эта формула работает в 2 или 3 измерениях.
Для двух измерений эта формула упрощается до указанной выше.
Ответ 4
Никто не указал, что если у вас есть один вектор, и вы хотите найти угол вектора от оси X, вы можете воспользоваться тем фактом, что аргумент atan2() на самом деле является наклоном линии, или (дельта Y/delta X). Так что, если вы знаете наклон, вы можете сделать следующее:
дано:
A = угол вектора/линии, которую вы хотите определить (от оси X).
m = знаковый наклон вектора/линии.
затем:
A = atan2 (м, 1)
Очень полезно!
Ответ 5
Если вам нужна точность для небольших углов, вы хотите использовать это:
angle = 2 * atan2 (|| || b || a - || a || b ||, || || b || a + || a || b ||)
Где "||" означает абсолютное значение, AKA "длина вектора". См. https://math.stackexchange.com/questions/1143354/numerically-stable-method-for-angle-between-3d-vectors/1782769
Однако это имеет недостаток, который в двух измерениях теряет знак угла.
Ответ 6
Вам не нужно использовать atan2 для вычисления угла между двумя векторами. Если вы просто хотите самый быстрый способ, вы можете использовать dot(v1, v2)=|v1|*|v2|*cos A
получить
A = Math.acos( dot(v1, v2)/(v1.length()*v2.length()) );
Ответ 7
В качестве дополнения к ответу @martin-r следует отметить, что можно использовать формулу суммы/разности для дуговых тангенсов.
angle = atan2(vec2.y, vec2.x) - atan2(vec1.y, vec1.x);
angle = -atan2(vec1.x * vec2.y - vec1.y * vec2.x, dot(vec1, vec2))
where dot = vec1.x * vec2.x + vec1.y * vec2.y
- Caveat 1: убедитесь, что угол остается в пределах -pi... + pi
- Caveat 2: будьте осторожны, когда векторы становятся очень похожими, вы можете исчезнуть в первом аргументе, что приведет к числовым неточностям
Ответ 8
angle(vector.b,vector.a)=pi/2*((1+sgn(xa))*(1-sgn(ya^2))-(1+sgn(xb))*(1-sgn(yb^2)))
+pi/4*((2+sgn(xa))*sgn(ya)-(2+sgn(xb))*sgn(yb))
+sgn(xa*ya)*atan((abs(xa)-abs(ya))/(abs(xa)+abs(ya)))
-sgn(xb*yb)*atan((abs(xb)-abs(yb))/(abs(xb)+abs(yb)))
xb, yb и xa, ya - координаты двух векторов
Ответ 9
Формула angle(vector.b,vector.a)
, которую я отправил, даст результаты
в четырех квадрантах и для любых координат xa,ya
и xb,yb
.
Для координат xa=ya=0
и или xb=yb=0
не определено.
Угол может быть больше или меньше, чем pi
, и может быть положительным
или отрицательный.