Найти угол между векторами в диапазоне от 0 до 360 градусов
Добре. Недавно начал перенос проекта на новый движок и столкнулся с рофлами, я не могу найти полное значение круга в градусах, т.к. скрип по какой-то причине вычисляет только внутренний угол, не затрагивая внешний. Вопрос - каким образом нужно написать скрипт, чтобы получить углы как на изображении ниже(отсчёт ведётся от синей линии, а все вектора направлены от центральной точки)
P.S. сейчас выводит 45, 0, 90. Должно выводить 45, 180, 270
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src="https://cdn.babylonjs.com/babylon.js"></script>
<script>
var mesharr = new BABYLON.Vector3(-6, 0, 6)
var baseV1 = new BABYLON.Vector3(0, 0, 5);
var baseV2 = new BABYLON.Vector3(-2, 0, 5);
var direction
var BaseVector = baseV1.subtract(baseV2);
var pointA1 = new BABYLON.Vector3(0, 0, 0);
var pointC1 = new BABYLON.Vector3(-2, 0, 2);
var vectorAA = pointA1.subtract(pointC1);
var angle_1 = angleBetweenVectorsInDegrees(BaseVector, vectorAA);
console.log(angle_1);//ожидается 45, на вывод 45
direction = vectorAA.dot(mesharr)
// Проверка направления вектора
if (direction > 0) {
console.log('к точке')
} else {
console.log('от точки')
}
var pointE1 = new BABYLON.Vector3(-14, 0, 5);
var pointF1 = new BABYLON.Vector3(-10, 0, 5);
var vectorEE = pointF1.subtract(pointE1);
var angle_2 = angleBetweenVectorsInDegrees(BaseVector, vectorEE);
console.log(angle_2);//ожидается 180, на вывод 0
direction = vectorEE.dot(mesharr)
// Проверка направления вектора
if (direction > 0) {
console.log('к точке')
} else {
console.log('от точки')
}
var pointG1 = new BABYLON.Vector3(-7, 0, 13);
var pointI1 = new BABYLON.Vector3(-7, 0, 15);
var vectorGG = pointG1.subtract(pointI1);
var angle_3 = angleBetweenVectorsInDegrees(BaseVector, vectorGG);
console.log(angle_3);//ожидается 270, на вывод 90
direction = vectorGG.dot(mesharr)
// Проверка направления вектора
if (direction > 0) {
console.log('к точке')
} else {
console.log('от точки')
}
function angleBetweenVectorsInDegrees(v1, v2) {
// Находим скалярное произведение векторов
const dotProduct = v1.x * v2.x + v1.z * v2.z;
// Находим длины векторов
const v1Length = Math.sqrt(v1.x * v1.x + v1.z * v1.z);
const v2Length = Math.sqrt(v2.x * v2.x + v2.z * v2.z);
// Вычисляем угол между векторами
let angle = Math.acos(dotProduct / (v1Length * v2Length));
// Преобразуем радианы в градусы
let degrees = angle * (180 / Math.PI);
return degrees;
}
</script>
</body>
</html>
Ответы (2 шт):
Уточнение
Если я вас правильно понимаю - v1 это начальная координата вектора, v2 это конечная координата. В таком случае вот что мы сделаем.
Решение
// Считаем базовые координаты вашего вектора
const difference = { x: v2.x - v1.x, y: v2.y - v1.y };
// Считаем угол тангенса с осью Y, но -y ставим так как отсчет начинается с минусовой части оси Y
let angle = Math.atan2(difference.x, -difference.y);
// Прибавляем к результату Пи, так как полученный угол у нас будет в диапазоне [-π; π]
angle += Math.PI;
Результат
angleCcw считает угол на который нужно повернуть первый вектор вокруг глобального нуля чтобы он совпал со вторым. Угол измеряется в радианах против часовой стрелки. Диапазон (-π, π].
angleBetweenVectorsInDegrees меняет местами вектора, чтобы считать угол по часовой стрелке, исправляет диапазон на [0, 2π), переводит радианы в градусы.
const angleCcw = (v1, v2) => Math.atan2(
v1.x * v2.z - v1.z * v2.x,
v1.x * v2.x + v1.z * v2.z
);
function angleBetweenVectorsInDegrees(v1, v2) {
let angle = angleCcw(v2, v1); // обратный порядок
// приведение в диапазон [0, 2PI)
if (angle < 0) {
angle += 2 * Math.PI;
}
// Преобразуем радианы в градусы
return angle * 180 / Math.PI;
}
console.log(angleBetweenVectorsInDegrees({x: 0, z: -1}, {x: 0, z: -1}));
console.log(angleBetweenVectorsInDegrees({x: 0, z: -1}, {x: -1, z: -1}));
console.log(angleBetweenVectorsInDegrees({x: 0, z: -1}, {x: -1, z: 0}));
console.log(angleBetweenVectorsInDegrees({x: 0, z: -1}, {x: -1, z: 1}));
console.log(angleBetweenVectorsInDegrees({x: 0, z: -1}, {x: 0, z: 1}));
console.log(angleBetweenVectorsInDegrees({x: 0, z: -1}, {x: 1, z: 1}));
console.log(angleBetweenVectorsInDegrees({x: 0, z: -1}, {x: 1, z: 0}));
console.log(angleBetweenVectorsInDegrees({x: 0, z: -1}, {x: 1, z: -1}));

