Как найти угол между двумя векторами на холсте?
4 ответа
По сути, вам нужно сделать точку, которая соединяет ваши два вектора, источником, где x=0 и y=0.
Посмотрите на эту картинку:
Теперь мы можем сказать, что значения x и y точек A, B и C:
- A = 0 | 0
- B = 0 | -6
- C = 5 | 2
Чтобы вычислить арктангенс обоих, мы можем использовать функцию Math.atan2(). Обратите внимание, что первым параметром для atan2 должно быть значение y.
var firstAngle = Math.atan2(-6, 0);
var secondAngle = Math.atan2(2, 5);
и получи их разницу вычитанием
var angle = secondAngle - firstAngle;
Это вернет значение в радианах, которое вы можете преобразовать в градусы следующим образом:
angle = angle * 180 / Math.PI;
Сначала вам нужно нормализовать два вектора.
Как только это будет сделано, вы можете сделать
angle = arcos(v1•v2)
где "угол" - это угол, который вы хотите найти, "аркос" - обратная функция косинуса, а "•" - оператор точечного произведения.
Будьте осторожны, это вернет только относительный и необработанный угол. Вы не сможете узнать, какой вектор находится слева, а какой - справа.
Если вам нужен 2D (
z=0
) и поддержку 3D , вы можете использовать
const dot = (p1, p2) => p1.x * p2.x + p1.y * p2.y + p1.z * p2.z;
С квадратной величиной (
magSq
), мы можем вычислить величину:
mag = Math.sqrt(magSq)
const magSq = ({x, y, z}) => x ** 2 + y ** 2 + z ** 2;
const mag = Math.sqrt(magSq(p));
Теперь мы можем вычислить продукт Dotточечное произведение и затем «нормализовать» его. Теперь используйте
acos()
чтобы получить угол:
const angle = Math.acos(dot(p1, p2) / Math.sqrt(magSq(p1) * magSq(p2)));
Мы также могли бы использовать Math.hypot()
, специальная функция JS для
mag
:
const mag = (p) => Math.hypot(p.x, p.y, p.z);
… И получить угол:
const angle = Math.acos(dot(p1, p2) / (mag(p1) * mag(p2)));
Пример:
Старый вопрос. Но я нашел хорошее решение. Допустим, у нас есть 4 точки, формирующие 2 вектора. точек (P0, P1, P2, P3), то угол P0P1 и P2P3 равен:
function angle2Vectors(ps) {
const v1 = { x: ps[1].x - ps[0].x, y: ps[1].y - ps[0].y };
const v2 = { x: ps[3].x - ps[2].x, y: ps[3].y - ps[2].y };
const l1_l2 = len(ps[1], ps[0]) * len(ps[3], ps[2]);
const v1_v2 = v1.x * v2.x + v1.y * v2.y;
const cos = v1_v2 / (len(ps[1], ps[0]) * len(ps[3], ps[2]));
const angCos = Math.acos(cos) * (180 / Math.PI);
const _v1_v2_ = v1.x * v2.y - v2.x * v1.y;
const sin = _v1_v2_ / l1_l2;
const angSin = Math.asin(sin) * (180 / Math.PI);
return angCos * Math.sign(angSin);
}