Вычисление угла
25 января 2016 20:11
Здравствуйте, я занимаюсь тем, что делаю эмулятор манипулятора.
На данном этапе мне критично получать углы в градусах и поворачивать на них же.
Вектора я формирую так: в редакторе blender я сделал сферы у начала и у конца моих звеньев, при чём назначил центром звена сферу, которая идёт у начала звена.
Так как у меня не получается воспользоваться встроенными методами для работы с векторами я написал незамысловатые свои на основе найденной в интернете информации.
Кода много, поэтому ссылка на github.
Визуально кажется, что теряется угол знака.
Вектора и углы формируются в файле manipulator.js, вот строки:
если просто поставить -, тогда с частью звеньев проблема пропадает, а с частью нет. Значит как мне кажется на вычислении угла где-то ошибка, тем более что функцию писал я)
На данном этапе мне критично получать углы в градусах и поворачивать на них же.
Вектора я формирую так: в редакторе blender я сделал сферы у начала и у конца моих звеньев, при чём назначил центром звена сферу, которая идёт у начала звена.
Так как у меня не получается воспользоваться встроенными методами для работы с векторами я написал незамысловатые свои на основе найденной в интернете информации.
Кода много, поэтому ссылка на github.
Визуально кажется, что теряется угол знака.
Вектора и углы формируются в файле manipulator.js, вот строки:
for(var len = armsNames.length, i = 1; i < len; i++) { // предполагается, что точек на 1 больше, чем armsNames
var vector1, vector2 = [];
var jointPoint = newArrayOfInitialPosition[i],// массив координат общего узла p[i]
array2 = newArrayOfInitialPosition[i-1], // массив координат предидущего узла p[i-1]
array3 = newArrayOfInitialPosition[i+1]; // массив координат следующего узла p[i+1]
vector1 = Vector.vectorFromCoord(array2,jointPoint); // формируем первый вектор
vector2 = Vector.vectorFromCoord(jointPoint,array3); // формируем второй вектор (это и есть наше звено)
thisArms[armsNames[i]].solvedRotation = Vector.radToAngle(Vector.angleBetweenTwoVectors(Vector.normalize(vector2),Vector.normalize(vector1)));
thisArms[armsNames[i]].rotateToAngle(this.AXIS.X,thisArms[armsNames[i]].solvedRotation);
console.log(thisArms[armsNames[i]].name,thisArms[armsNames[i]].solvedRotation); // Выводит имя и угол поворота звена
если просто поставить -, тогда с частью звеньев проблема пропадает, а с частью нет. Значит как мне кажется на вычислении угла где-то ошибка, тем более что функцию писал я)
26 января 2016 11:15
Добрый день.
Пробежался глазами по вашим функциям для рассчета угла между векторами.
Давайте рассмотрим функцию нахождения угла.
В идеале ваша формула должна иметь вид для векторов a и b:
atan (( |a| * |b| * sin(alpha)) / (( |a| * |b| * cos(alpha))
где информация о знаке угла заложена в нечетной функции sin.
Но у вас в формуле расчет идет через модуль вектора, полученного в результате векторного произведения. И формула принимает вид:
atan (( |a| * |b| * |sin(alpha)|) / (( |a| * |b| * cos(alpha))
Таким образом потерялась информация о направлении вектора, полученного в результате векторного произведения.
Обратите внимание на эту статью (тут вас должны заинтересовать формулы и таблицы):
http://www.euclideanspace.com/maths/algebra/vectors/angleBetween/
Она должна вам помочь сохранить знак векторного произведения.
Пробежался глазами по вашим функциям для рассчета угла между векторами.
Давайте рассмотрим функцию нахождения угла.
// Функция для вычисления угла между 2 векторами
Vector.angleBetweenTwoVectors = function(vector1, vector2) {
// скалярное произведение векторов
// Вычисляем косинус угла между векторами
return Math.atan2(Vector.module(Vector.vecMultVectors(vector1,vector2)),Vector.scalMultVectors(vector1,vector2));
};
В идеале ваша формула должна иметь вид для векторов a и b:
atan (( |a| * |b| * sin(alpha)) / (( |a| * |b| * cos(alpha))
где информация о знаке угла заложена в нечетной функции sin.
Но у вас в формуле расчет идет через модуль вектора, полученного в результате векторного произведения. И формула принимает вид:
atan (( |a| * |b| * |sin(alpha)|) / (( |a| * |b| * cos(alpha))
Таким образом потерялась информация о направлении вектора, полученного в результате векторного произведения.
Обратите внимание на эту статью (тут вас должны заинтересовать формулы и таблицы):
http://www.euclideanspace.com/maths/algebra/vectors/angleBetween/
Она должна вам помочь сохранить знак векторного произведения.