Вероятно, наиболее интуитивно понятно вращать объект вокруг оси, перпендикулярной текущему направлению перетаскивания, либо постепенно, с каждым движением мыши, либо относительно начальной позиции перетаскивания. Эти два параметра дают немного отличающиеся пользовательские взаимодействия, у каждого из которых есть свои плюсы и минусы.
Существует относительно простой способ преобразования угла и трехмерный вектор, представляющий вращаемую ось в матрицу вращения.
Вы правы в том, что обновление необработанной матрицы вращения посредством инкрементных вращений приведет к тому, что матрица больше не будет чистой матрицей вращения. Это связано с тем, что матрица вращения 3x3 содержит в три раза больше данных, чем необходимо для представления вращения.
Более компактный способ представления поворотов - Углы Эйлера , имеющие минимальный вектор 3 значений. Вы можете взять текущее вращение в качестве вектора угла Эйлера, преобразовать его в матрицу, применить вращение (в инкрементном или ином виде) и преобразовать матрицу обратно в вектор угла Эйлера. Этот последний шаг естественным образом исключит любой невращающийся компонент в вашей матрице, так что вы снова получите чистую вращательную матрицу для следующего состояния.
Углы Эйлера концептуально хороши, однако для преобразования туда и обратно требуется много работы.
Более практичный выбор - Кватернионы ( также ), которые представляют собой четырехэлементные векторы. Четыре элемента определяют вращение и равномерный масштаб, и бывает, что если вы войдете и нормализуете вектор до длины единицы, вы получите масштабный коэффициент 1,0. Оказывается, что значение оси угла также можно очень легко преобразовать в значение кватерниона с помощью
q.x = sin(0.5*angle) * axis.x;
q.y = sin(0.5*angle) * axis.y;
q.z = sin(0.5*angle) * axis.z;
q.w = cos(0.5*angle);
Затем вы можете взять произведение кватернионов (которое использует только простое умножение и сложение) текущего кватерниона вращения и кватерниона инкрементного вращения, чтобы получить новый кватернион, представляющий выполнение обоих вращений. В этот момент вы можете нормализовать длину, чтобы обеспечить чистое вращение, но в противном случае продолжить итеративное объединение вращений.
Преобразование кватерниона в матрицу вращения очень просто (используется только умножение и сложение), когда вы хотите отобразить модель в повернутом состоянии с использованием традиционных графических API.