Вычисление угла

25 января 2016 20:11 #6801
Здравствуйте, я занимаюсь тем, что делаю эмулятор манипулятора.
На данном этапе мне критично получать углы в градусах и поворачивать на них же.
Вектора я формирую так: в редакторе 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 #6810
Добрый день.

Пробежался глазами по вашим функциям для рассчета угла между векторами.
Давайте рассмотрим функцию нахождения угла.
// Функция для вычисления угла между 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/
Она должна вам помочь сохранить знак векторного произведения.
Разработчик Blend4Web
 
Пожалуйста, зарегистрируйтесь или войдите под своей учетной записью , чтобы оставлять сообщения.