Я учусь использовать нормализованные векторы в моих играх.
Я узнал, что для того, чтобы узнать угол между двумя векторами, я могу использовать скалярное произведение. Это дает мне значение от -1 до 1, где
- 1 означает, что векторы параллельны и направлены в одном направлении (угол составляет 180 градусов).
- -1 означает, что они параллельны и обращены в разные стороны (еще 180 градусов).
0
означает, что угол между ними составляет 90 градусов.
Я хочу знать, как преобразовать скалярное произведение двух векторов в фактический угол в градусах. Например, если скалярное произведение двух векторов равно 0.28
какому соответствующему углу от 0 до 360 градусов?
2d
mathematics
vector
geometry
user3150201
источник
источник
Ответы:
dot(A,B) = |A| * |B| * cos(angle)
который может быть переставлен в
angle = arccos(dot(A,B) / (|A|* |B|))
.С помощью этой формулы вы можете найти наименьший угол между двумя векторами, который будет между 0 и 180 градусами. Если вам нужно от 0 до 360 градусов, этот вопрос может вам помочь.
Кстати, угол между двумя параллельными векторами, указывающими в одном направлении, должен быть 0 градусов, а не 180.
источник
Я немного расширю комментарий TravisG и дам другой ответ, используя тот факт, что ваш вопрос имеет тег «2D».
Вы можете получить угол между двумя векторами , используя скалярное произведение, но вы не можете получить подписанный угла между двумя векторами , используя его. Иными словами, если вы хотите со временем повернуть персонажа к точке, точечный продукт даст вам, сколько повернуть, а не в каком направлении. Однако есть еще одна простая формула, которая очень полезна в сочетании с точечным произведением. Не только у вас есть
dot(A,B) = |A| * |B| * cos(angle)
У вас также может быть другая формула (имя которой я придумал для политкорректности):
pseudoCross(A,B) = |A| * |B| * sin(angle)
где, если A = (a, b), B = (x, y), то псевдокросс (A, B) определяется как третий компонент кросс-произведения (a, b, 0) x (x, y, 0 ). Другими словами:
a*x+b*y = |A| * |B| * cos(angle)
-b*x+a*y = |A| * |B| * sin(angle)
Тогда полный угол со
angle=atanfull(-b*x+a*y,a*x+b*y)
знаком равен (функции atanfull или atan2 простят вас, если вы передаете ненормализованные значения). Если A и B нормализованы, то есть, если|A|=|B|=1
это просто:a*x+b*y = cos(angle)
-b*x+a*y = sin(angle)
Для более глубокого объяснения обратите внимание, что приведенные выше уравнения могут быть выражены матричным уравнением:
Но и Ь может быть выражен как
a=cos(ang1)
,b=sin(ang1)
для некоторого значенияang1
(неangle
). Следовательно, матрица слева является матрицей вращения, которая поворачивает вектор (x, y) на величину -ang1. Это эквивалентно переходу в систему отсчета, где единичный вектор «А» рассматривается как вектор / ось (1,0)! Итак, просто нарисовав единичную окружность / прямоугольный треугольник в этом кадре, вы можете увидеть, почему результирующий вектор этого произведения равен (cos (угол), sin (угол)).Если вы напишите (a, b) и (x, y) в полярной форме и примените формулы разности углов,
cos(l)*cos(m)+sin(l)*sin(m)=cos(l-m)
иsin(l)*cos(m)-cos(l)*sin(m)=sin(l-m)
вы повторно выразите, что синус / косинус задаются этим продуктом, поскольку (lm) = угол. Альтернативно, эти тождества могут быть использованы, чтобы понять, почему приведенное выше линейное произведение вращает вектор.Все эти идентичности означают, что вам редко нужны углы. Поскольку углы могут быть странными - радианы / градусы, условные обозначения для обратных синусов / косинусов, тот факт, что они повторяются каждые 2 * пи - это может быть более полезным и сэкономить вам кучу логики «если (анг <180)» и т. Д.
источник