OpenGL - вращение вокруг куба с помощью gluLookAt вращается очень быстро
Я пытаюсь перемещаться по кубу с центром в начале координат, используя gluLookAt вместо того, чтобы выполнять преобразование R*T непосредственно на объекте. Сначала я не был уверен, как решить эту проблему. Затем я понял (после реализации половины решения в круговых координатах), что я должен попытаться использовать представление сферической системы координат. Я смог написать некоторый код для этого, но я ("глаз" камеры) действительно быстро вращаюсь вокруг куба. Кроме того, я замечаю, что я двигаюсь немного ближе к кубу, а не держу постоянный радиус. Когда я использую метод Rotate*Translate, он вращается с более правильной скоростью на том же расстоянии.
Мой подход к вращению состоял в том, чтобы использовать сферические координаты, но я не уверен, что это правильно. Я рассчитываю два угла, согласно диаграмме, расположенной на странице Википедии. Я рассчитываю величину текущей точки, в которой я нахожусь (distX, distY, distZ). Мы изначально находимся в плоскости XY и смотрим на отрицательную плоскость Z). Мне также дают два угла, один для указания угла поворота вокруг оси X и один для оси Y. Эти пять значений рассчитываются на основе того, как сделаны мои щелчки мыши.
Я вычисляю тэту и фи на основе некоторого трига, а затем, наконец, новую позицию. Эти формулы можно найти в этой ссылке ранее. Последний шаг - подключить его к gluLookAt. Опять же, после запуска этой программы я могу вращаться вокруг куба, но он очень быстрый и переводит камеру также. Что я делаю неправильно?
Мой код указан ниже, если вы хотите сослаться на него. Часть, ссылающаяся на "у" и "вверх", - мои попытки вычислить вращение вокруг оси Z. Лучше всего я могу описать это вращение, если посмотреть на объект, представить себя камерой и наклонить голову влево и вправо. Я не включил его в свой вызов gluLookAt, так как не мог заставить это работать.
РЕДАКТИРОВАТЬ: теперь он вращается с правильной скоростью, но не вращается полностью. Под этим я подразумеваю, что при вращении "глаз" движется к кубу под углом, но затем поворачивается назад, отменяя вращение. Но это повторяет петлю, поэтому путь, пройденный глазом, выглядит как согнутый символ бесконечности.
void sceneTransformation(){
glLoadIdentity( );
//Using the R*T approach. Works flawlessly
//glTranslatef(-distX, distY, -distZ);
//glRotatef( anglex, 1.0, 0.0, 0.0 );
//glRotatef( angley, 0.0, 1.0, 0.0 );
GLdouble radx = anglex*PI/180.;
GLdouble rady = angley*PI/180.;
GLdouble l = sqrt(pow(distX, 2) + pow(distY, 2) + pow(distZ, 2));
GLdouble phi = atan(distY/distZ) + radx;
GLdouble theta = acos(distZ/l) + radx;
GLdouble deltaZ = l*sin(theta)*cos(phi);
GLdouble deltaY = l*sin(theta)*sin(phi);
GLdouble deltaX = l*cos(theta);
GLdouble ytheta = atan(distX/distY);
GLdouble y = sqrt(pow(distX,2) + pow(distY, 2));
GLdouble yangle = PI/2.-ytheta-rady;
GLdouble up_y = y*sin(yangle);
GLdouble up_x = y*cos(yangle);
gluLookAt((distX - deltaX), (distY - deltaY), (distZ - deltaZ), 0, 0, 0, 0,1,0);
}
3 ответа
Математические функции, такие как sin()
, cos()
и друзья ожидают ввода в радианах, а не градусах. Похоже, вы принимаете градусы, поэтому вы вращаетесь примерно в 57,3 раза (точнее: 360 / (2 * пи)) быстрее, чем предполагалось.
Вы должны сделать свое движение основанным на времени, это означает, чтобы умножить угол поворота на дельту между начальным последним и текущим кадром.
angle += 90 * timeDelta; // Rotate by 90 degree each second
Есть прекрасное решение вашей проблемы. возьмите немного исследования, но я думаю, что это удовлетворит ваши потребности. Кватернионы
Хорошо для преобразования вектора в вращение и назад