Да, я тоже столкнулся с этой проблемой.
Что вам нужно сделать, так это сохранить матрицу вращения, которая "накапливает" текущее состояние вращения, и использовать ее в дополнение к матрице вращения, которая приходитиз текущей операции перетаскивания.
Скажем, у вас есть две матрицы, lastRotMx и currRotMx.Сделайте их членами CubeDrawingArea, если хотите.
Вы не показали нам это, но я предполагаю, что m_lastTrackPoint инициализируется всякий раз, когда кнопка мыши нажимается для перетаскивания.Когда это произойдет, скопируйте currRotMx в lastRotMx.
Затем в on_motion_notify_event()
, после вычисления m_rotAxis и m_angle, создайте новую матрицу вращения draggingRotMx на основе m_rotAxis и m_angle;затем умножьте lastRotMx с помощью draggingRotMx и поместите результат в currRotMx.
Наконец, в redraw()
вместо
glRotated(m_angle, m_rotAxis.x, m_rotAxis.y, m_rotAxis.z);
поверните на currRotMx.
Обновление: Или вместо всего этого ... Я не проверял это, но я думаю, что это сработало бы:
Сделайте cur_pos членом класса, чтобы он оставался, но он был инициализирован нулем, какm_lastTrackPoint.Затем, всякий раз, когда начинается новое движение перетаскивания, перед инициализацией m_lastTrackPoint, пусть _3V dpos = cur_pos - m_lastTrackPoint (псевдокод).Наконец, когда вы инициализируете m_lastTrackPoint на основе координат события мыши, вычтите из него dpos.
Таким образом, ваши cur_pos уже будут смещены от m_lastTrackPoint на величину, основанную на накоплении смещений от прошлых перетаскиваний дуги.
Вероятно, ошибка также будет накапливаться, но она должна быть достаточно постепенной, чтобы не быть заметной.Но я хотел бы проверить это, чтобы убедиться, что составные ротации достаточно сложны, и я не доверяю им, не увидев их.
PS Ваше имя пользователя демотивирует.Предложите выбрать еще один.
PPS Для тех, кто позже ищет ответы на этот вопрос, ключевые слова для поиска: « arcball вращение ».Окончательной статьей является раздел Кена Шумейка в Graphical Gems IV .Смотрите также этот учебник по Arcball для JOGL .