(iPhone) Я пытаюсь сделать так, чтобы пользователь мог вращать объект, проводя пальцем по экрану. Перетаскивание влево или вправо должно вращаться вокруг оси Y, а перетаскивание вверх или вниз должно вращаться вокруг оси X. Вот мой оригинальный код:
glRotatef( yAmt, 0, 1, 0 );
glRotatef( xAmt, 1, 0, 0 );
Вращение все сумасшедшее и, кажется, идет в случайных направлениях. Я почти уверен, что это связано с тем, что второе утверждение зависит от первого, но я пытался отрицать это с помощью какой-то причудливой математики и все еще не мог понять это правильно.
Ну, я частично понял это, но теперь у меня есть новая проблема (как сложить два поворота?).
МОЕ РЕШЕНИЕ:
Допустим, вы хотели повернуть куб влево на 90, а затем на 90. Попробуйте следующее:
glRotatef( 90, 0, 1, 0 );
glRotatef( 90, 1, 0, 0 );
Это не работает. Вторая функция ведет себя странно, потому что первая функция поменяла местами оси X и Z. Итак, вы попробуйте это:
glRotatef( 90, 0, 1, 0 );
glRotatef( 90, 0, 0, 1 );
Теперь у вас есть желаемый результат, но если вы измените величину вращения Y в первой функции на 180 или 45 или что-то еще, он снова потерпит неудачу. Требуемый вектор вращения зависит от величины вращения Y от первой функции. Желаемый результат достигается с помощью:
glRotatef( yAmt, 0, 1, 0 );
glRotatef( xAmnt, cos(yAmt), 0, sin(yAmt) );
А что если вы хотите сначала повернуть вверх и вниз, а затем слева направо? Это последнее решение терпит неудачу, потому что, во-первых, функции находятся в неправильном порядке, и, во-вторых, ось Y также зависит от вращения X. Вы должны учитывать это, И вы должны объединить две функции, в результате чего:
glRotatef( totalAmt, xFactor*cos(yAmt), yFactor*cos(xAmt), xFactor*sin(yAmt) + yFactor*sin(xAmt) );
Где xFactor и yFactor складываются с требуемым вектором вращения (1,0 для вверх и вниз, 0,1 для левого и правого, sqrt (.5), sqrt (.5) для диагонального вращения).
МОЯ ПРОБЛЕМА:
Проблема возникает, когда пользователь заканчивает один оборот и начинает новый. Вы должны запомнить и «повторно активировать» предыдущее вращение, в противном случае вы получите нежелательный «прыжок» назад к 0 вращению. Один новый поворот - это хорошо, я могу реализовать touchesEnded, чтобы запомнить параметры glRotatef, а затем подключить их к новому повороту, например так:
glRotatef( amt_old, x_old, y_old, z_old );
glRotatef( totalAmt, xFactor*cos(yAmt), yFactor*cos(xAmt), xFactor*sin(yAmt) + yFactor*sin(xAmt) );
Но во втором новом вращении у меня теперь есть два поворота для "повторной активации". Я не могу понять, какие значения присвоить amt_old, x_old, y_old и z_old. К чему это сводится ... как вы суммируете два вращения glRotatef?