Попробуйте VTD-XML . Я обнаружил, что он более эффективен и, что более важно, проще в использовании, чем SAX.
РЕДАКТИРОВАТЬ 3: Мне пришло в голову, что приведенное ниже решение, хотя и является правильным, излишне сложно. Вы можете добиться того же эффекта, просто умножив матрицу вращения на матрицу ориентации для вычисления новой ориентации:
M = R * M
Хотя это не имеет отношения к вопросу, это также правильно обрабатывает матрицы ориентации, которые не состоят из чистого вращения, но также содержат сдвиг, перекос и т. д.
(Конец редактирования 3)
Вам нужна матрица преобразования, содержащая текущие повернутые оси локальной системы координат вашего объекта. Затем вы применяете вращения к этой матрице.
В математических терминах вы начинаете с единичной матрицы следующим образом:
M = [1 0 0 0]
[0 1 0 0]
[0 0 1 0]
[0 0 0 1]
Эта матрица состоит из трех векторов, U, V и W, которые представляют - в мировых координатах - три единичных вектора локальной системы координат вашего объекта:
M = [Ux Vx Wx 0]
[Uy Vy Wy 0]
[Uz Vz Wz 0]
[0 0 0 1]
Если вы хотите повернуть объект, поверните каждый вектор на месте . Другими словами, примените вращение независимо к каждому из U, V и W в матрице.
При визуализации просто примените M как единое преобразование к вашему объекту. (В случае, если вам интересно, не применяйте сами повороты; только матрицу.)
РЕДАКТИРОВАТЬ 2: (Появляется перед первым редактированием, поскольку он предоставляет контекст для него.)
При повторном просмотре этого ответа спустя много времени после того, как он был первоначально опубликован, я понял, что, возможно, я не уловил из-за недопонимания, которое может возникнуть у вас по поводу того, как применять ротацию для каждого элемента управления.
Идея состоит не в том, чтобы накапливать вращение, применяемое каждым элементом управления, а применять их отдельно. Скорее, вы должны применять каждое инкрементное вращение (т.е. каждый раз, когда один из ваших ползунков запускает событие изменения) немедленно к векторам U, V и W.
Говоря более конкретно, не говорите: «Всего вертикальный элемент управления переместился на 47 °, а горизонтальный элемент управления - на -21 °» и применяйте их как два больших поворота. Это покажет ту же проблему, которая послужила причиной вашего вопроса. Вместо этого скажите: «Вертикальный ползунок только что переместился на 0,23 °» и поверните U, V и W вокруг оси X на 0,23 °.
Короче говоря, поворот на 90 ° с последующим наклоном 45 °, описанный ниже, вероятно, не то, что вам нужно.
РЕДАКТИРОВАТЬ: В соответствии с запросом, вот как на практике реализуется случай рыскания 90 ° с последующим шагом 45 ° ...
Поскольку вы начинаете с единичной матрицы, базисные векторы будут просто вашим миром единичные векторы:
U = [1] V = [0] W = [0]
[0] [1] [0]
[0] [0] [1]
Чтобы применить рыскание на 90 °, поверните каждый базисный вектор вокруг оси Z (отражая мой математический наклон), что почти тривиально:
U = [0] V = [-1] W = [0]
[1] [ 0] [0]
[0] [ 0] [1]
Таким образом, после поворота на 90 ° матрица преобразования будет :
M = [0 -1 0 0]
[1 0 0 0]
[0 0 1 0]
[0 0 0 1]
Применение этой матрицы к объекту приведет к желаемому повороту на 90 ° вокруг Z.
Чтобы затем применить угол наклона 45 ° (который я буду считать вокруг оси X), мы поворачиваем наши новые базисные векторы в плоскости YZ, на этот раз на 45 °:
U = [0 ] V = [-1] W = [ 0 ]
[0.7] [ 0] [-0.7]
[0.7] [ 0] [ 0.7]
Таким образом, новый матрица преобразования:
M = [0 -1 0 0]
[0.7 0 -0.7 0]
[0.7 0 0.7 0]
[0 0 0 1]
Если вы умножите два поворота вместе:
Yaw(90)*Pitch(45) = [0 -1 0 0]*[1 0 0 0] = [0 -0.7 0.7 0]
[1 0 0 0] [0 0.7 -0.7 0] [1 0 0 0]
[0 0 1 0] [0 0.7 0.7 0] [0 0.7 0.7 0]
[0 0 0 1] [0 0 0 1] [0 0 0 1]
Pitch(45)*Yaw(90) = [1 0 0 0]*[0 -1 0 0] = [0 -1 0 0]
[0 0.7 -0.7 0] [1 0 0 0] [0.7 0 -0.7 0]
[0 0.7 0.7 0] [0 0 1 0] [0.7 0 0.7 0]
[0 0 0 1] [0 0 0 1] [0 0 0 1]
Вы заметите, что вторая форма такая же, как матрица преобразования, созданная путем манипулирования базисными векторами, но это просто совпадение (и довольно обычная при смешивании поворотов на 90 ° и 45 °). В общем случае ни один из порядков применения не соответствует базисному преобразованию.
Я выдохся, так что я надеюсь, что объяснение до сих пор проясняет ситуацию, а не делает ее более запутанной.