Мне нужно найти угол между двумя векторами на моем холсте. Ниже я прикрепил несколько примеров:
Не могли бы вы посоветовать мне какую-нибудь формулу? У меня проблемы со школьной математикой :)
У меня есть начальная точка каждой линии, поэтому я думаю, что это вектор
Так 5''0' и 4''3' их длина? Или это координаты?
Это их длина.
Так где же координата 0 на картинке?
В левом верхнем углу картинки.
Сначала вам нужно нормализовать для двух векторов.
Как только это будет сделано, вы можете сделать
angle = arcos(v1•v2)
где «угол» — это угол, который вы хотите найти, «аркос» — функция, обратная косинусу, а «•» — оператор скалярного произведения.
Будьте осторожны, это вернет только относительный и необработанный угол. Вы не сможете узнать, какой вектор слева, а какой справа.
как рассчитать этот v1 * v2? V1 и V2 состоят из двух точек.
Это работает, даже если вы не нормализуете его. Вы можете отличить левое от правого, если воспользуетесь правилом правой руки: возьмите перекрестное произведение. Знак говорит вам влево или вправо.
В основном вам нужно сделать точку, которая соединяет ваши два вектора в начале координат, где x = 0 и y = 0.
Взгляните на эту картинку:
Теперь мы можем сказать, что значения x и y точек А, Б и С равны:
Чтобы вычислить арктангенс обоих, мы можем использовать функцию 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;
0|-6 и 5|2 — это не точки, а длина. Но это не имеет значения. попробую и прокомментирую. Спасибо!
Я использовал эту формулу, но когда я построил фигуру, как на первой картинке, я получил 0. Но реальный угол равен 90.
Если я использую -5|0 для точки вверху слева и 0|5 для точки внизу справа, я получаю 90 градусов – как и ожидалось.
Для C 5|2 не правильные координаты. Это длина.
Не запутайтесь, я не говорю о длине (которая является величиной вектора). Я говорю о направлении от центральной точки A. В моем ответе выше вам нужно пройти 5 блоков вправо и ~ 2 блока вниз, чтобы добраться из точки A в точку C -> это вектор. Это просто совпадение, что длина на вашей картинке тоже 5 дюймов 2 фута.
Итак, длина вектора (5,2) будет равна sqrt (5*5 + 2*2), верно? то есть 5,38.
Значит, это не вектор с координатами (5,2)
Ну, у вектора нет координат - у него есть направление (от относительного положения). Это относительное положение — точка А, и чтобы добраться до точки С, вам нужно переместиться на 5 блоков вправо и на 2 блока вниз, таким образом, 5|2. То же самое с точкой B - вам нужно переместиться на 6 блоков вверх (-6) и не нужно двигаться по горизонтали (0).
И из этого относительного положения вектор будет (5,2). Если мы примем, что точка A равна (0,0). Тогда вычисление длины этого вектора по приведенной выше формуле — длина вектора на картинке — не совпадает. Я предполагаю, что изображения в вопросе не очень точны. Если приглядеться, то точка C на самом деле не достигает угла.
Да, это больше похоже на 4,9|1,8, но я хотел упростить ситуацию, используя целые числа.
Кажется, я знаю, в чем проблема. Точка А не имеет координат (0,0) Опишу данные картинки. B - (180, 30) A - (180, 210) C - (330, 270) 0, 0 координаты в левом правом углу экрана.
Чтобы сделать начало точки (0,0) — которая должна быть точкой A в нашем примере — вы должны вычесть ее положение из всех других точек. Итак, если это A(180,210) B(180,30) C(330,270), выполните B.x-A.x B.y-A.y, чтобы получить (0,-180), и C.x-A.x C.y-A.y, чтобы получить (150,60). Теперь снова выполните расчет в моем ответе с этими значениями.
Если вам нужна поддержка 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));
Теперь мы можем вычислить Скалярное произведение и впоследствии «нормализовать» его.
Теперь используйте 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)));
let a = {x: 0, y: -6, z: 0};
let b = {x: 5, y: 2, z: 0}; // set z != 0 for 3D
let dot = (p1, p2)=> p1.x * p2.x + p1.y * p2.y + p1.z * p2.z;
let magSq = ({x, y, z}) => x ** 2 + y ** 2 + z ** 2;
let angle1 = Math.acos(dot(a, b) / Math.sqrt(magSq(a) * magSq(b)));
console.info('1. Angle:', angle1); // 1.9513027
// ... or
let mag = ({x, y, z}) => Math.hypot(x, y, z);
let angle2 = Math.acos(dot(a, b) / (mag(a) * mag(b)))
console.info('2. Angle:', angle2); // 1.9513027
Это вектор или сегмент?