Как всегда вращаться с определенной ориентации

Попробуйте VTD-XML . Я обнаружил, что он более эффективен и, что более важно, проще в использовании, чем SAX.

1
задан lzcd 22 July 2010 в 09:53
поделиться

1 ответ

РЕДАКТИРОВАТЬ 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 °). В общем случае ни один из порядков применения не соответствует базисному преобразованию.

Я выдохся, так что я надеюсь, что объяснение до сих пор проясняет ситуацию, а не делает ее более запутанной.

2
ответ дан 2 September 2019 в 22:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: