Вращающиеся объекты - PullRequest
0 голосов
/ 07 декабря 2010

У меня есть объект (конус) с основанием на вершине X1 (основание окружности конуса имеет центр на X1) и указывает на Оз. Я хотел бы повернуть его, чтобы он указывал на данную вершину X2. Я перепробовал много комбинаций, я сделал много вычислений, все еще не могу заставить это работать. Было бы неплохо, если бы вы могли дать ответ, используя функцию C ++ OpenGL glRotatef, но общий ответ также был бы оценен. Сейчас я пытаюсь сделать это на конусе, но он должен работать на любой сетке.

Пока у меня есть это:

h1 = sqrt(pow(p2.y - p1.y, 2) + pow(p2.z - p1.z, 2));
h2 = sqrt(pow(p2.x - p1.x, 2) + pow(p2.z - p1.z, 2));
h3 = sqrt(pow(p2.x - p1.x, 2) + pow(p2.y - p1.y, 2) + pow(p2.z - p1.z, 2));

r.x = sign(p1.y-p2.y)*acos((p1.z-p2.z)/h1) * 180/M_PI;
r.y = sign(p1.x-p2.x)*acos((p1.z-p2.z)/h2) * 180/M_PI;
r.z = 0;

cone.SetPosition(p2);
cone.SetHeight(h3);
cone.SetRotation(r);

Где sign () - это его имя, возвращает -1 для отрицательного значения и 1 для положительного параметра. И функция рисования объекта Cone выглядит следующим образом:

void drawCone()
{
    glPushMatrix();
    glTranslatef(pos.x, pos.y, pos.z);
    glRotatef(rot.x, 1, 0, 0);
    glRotatef(rot.y, 0, 1, 0);
    glRotatef(rot.z, 0, 0, 1);
    glColor3f(col.red, col.green, col.blue);
    gluDisk(cone, 0, radius, 10, 10);
    gluCylinder(cone, radius, 0, height, 10, 10);
    glPopMatrix();
}

Это не должно быть высоко оптимизированное решение, просто рабочее.

1 Ответ

4 голосов
/ 07 декабря 2010

Если я правильно понимаю ваш вопрос, вы в основном хотите повернуть один вектор на другой по кратчайшему сферическому пути - вот к чему обычно сводится прицеливание. В общем случае с углами Эйлера это немного болезненно. У меня где-то есть код, который целиком и полностью нацелен на углы Эйлера, но он слишком сложен - если по какой-то причине вам придется делать это с углами Эйлера, я мог бы выкопать его.

Но то, что вы действительно хотите здесь сделать, ИМХО, это использовать кватернионное представление. Это делает вещи очень простыми. Вы просто берете вектор, на который хотите повернуть, и вектор, на который хотите повернуть, и находите их перекрестное произведение. Это ось, вокруг которой вы хотите вращаться. Затем найдите угол между двумя векторами - это величина, на которую вы хотите повернуть. Вращение на определенную величину вокруг определенной оси - это то, что кватернионы делают лучше всего - есть особенность, если вы хотите повернуть на ось, которая указывает точно в противоположном направлении от вашего исходного вектора, - но это неизбежно и может не иметь большого значения для что ты делаешь.

РЕДАКТИРОВАТЬ: также не так сложно вычислить матрицу вращения непосредственно, учитывая угол и ось. Но в каждом случае, когда мне приходилось делать это, я должен был иметь возможность интерполировать кадры вращения. Вот почему я предлагаю использовать кватернионы. Если вам не нужно интерполировать плавно, любой метод получения поворота от оси и угла будет в порядке.

...