Я читаю онлайн книгу Джейсона МакКессона «Обучение современному программированию в трехмерной графике».
На данный момент я имею дело с проблемой блокировки карданного подвеса и с тем, как ее решить с помощью кватернионов.
Однако прямо здесь, на странице Quaternions .
Часть проблемы заключается в том, что мы пытаемся сохранить ориентацию в виде серии из 3-х накопленных осевых вращений. Ориентации - это ориентации, а не вращения. И ориентации, конечно, не серия вращений. Поэтому нам нужно рассматривать ориентацию корабля как ориентацию, как определенную величину.
Я думаю, это первое место, где я начинаю путаться, причина в том, что я не вижу резкой разницы между ориентациями и поворотами. Я также не понимаю, почему ориентация не может быть представлена серией вращений ...
Также:
Первой мыслью в этом направлении было бы сохранение ориентации в виде матрицы. Когда приходит время изменить ориентацию, мы просто применяем преобразование к этой матрице, сохраняя результат как новую текущую ориентацию.
Это означает, что каждый рывок, тангаж и крен, примененные к текущей ориентации, будут относительно этой текущей ориентации. Что именно то, что нам нужно. Если пользователь применяет положительное отклонение, вам нужно, чтобы отклонение поворачивало их относительно текущего направления, а не относительно некоторой фиксированной системы координат.
Понятие, которое я понимаю, однако я не понимаю, как, если накопление матричных преобразований является решением этой проблемы, как код, приведенный на предыдущей странице , не только это.
Вот код:
void display()
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glutil::MatrixStack currMatrix;
currMatrix.Translate(glm::vec3(0.0f, 0.0f, -200.0f));
currMatrix.RotateX(g_angles.fAngleX);
DrawGimbal(currMatrix, GIMBAL_X_AXIS, glm::vec4(0.4f, 0.4f, 1.0f, 1.0f));
currMatrix.RotateY(g_angles.fAngleY);
DrawGimbal(currMatrix, GIMBAL_Y_AXIS, glm::vec4(0.0f, 1.0f, 0.0f, 1.0f));
currMatrix.RotateZ(g_angles.fAngleZ);
DrawGimbal(currMatrix, GIMBAL_Z_AXIS, glm::vec4(1.0f, 0.3f, 0.3f, 1.0f));
glUseProgram(theProgram);
currMatrix.Scale(3.0, 3.0, 3.0);
currMatrix.RotateX(-90);
//Set the base color for this object.
glUniform4f(baseColorUnif, 1.0, 1.0, 1.0, 1.0);
glUniformMatrix4fv(modelToCameraMatrixUnif, 1, GL_FALSE, glm::value_ptr(currMatrix.Top()));
g_pObject->Render("tint");
glUseProgram(0);
glutSwapBuffers();
}
Насколько я понимаю, не то, что он делает (модифицирует матрицу в стеке), рассматривает накопление матриц, поскольку автор объединил все отдельные преобразования вращения в одну матрицу, которая хранится в верхней части стека.
Насколько я понимаю, матрица состоит в том, что они используются для определения точки, относящейся к источнику (скажем, модели), и для ее сопоставления с другим источником (камерой). Я почти уверен, что это безопасное определение, однако я чувствую, что чего-то не хватает, что мешает мне понять эту проблему блокировки карданного подвеса.
Одна вещь, которая не имеет смысла для меня: если матрица определяет разницу между двумя «пробелами», то почему вращение вокруг оси Y для, скажем, вращения, не ставит точку в «пространстве прокрутки» «который затем может быть снова преобразован по отношению к этому броску ... Другими словами, никакие дальнейшие преобразования в этой точке не должны относиться к этому новому« пространству вращения »и, следовательно, не должны иметь вращение относительно предыдущего» Модельное пространство », вызывающее карданный замок.
Вот почему блокировка кардана происходит правильно? Это потому, что мы вращаем объект вокруг осей X, Y и Z, а не вращаем объект вокруг его собственных относительных осей. Или я не прав?
Поскольку этот код, на который я ссылаюсь, не является накоплением матричных преобразований, приведите пример решения, использующего этот метод.
Итак, в заключение:
- В чем разница между вращением и ориентацией?
- Почему код связан не с примером накопления матричных преобразований?
- Какова реальная, конкретная цель матрицы, если я ошибся?
- Как можно решить проблему блокировки карданного подвеса с помощью накопления матричных преобразований?
- Кроме того, в качестве бонуса: почему преобразования после поворота по-прежнему относятся к «пространству модели»?
- Еще один бонус: я ошибаюсь в предположении, что после трансформации будут происходить дальнейшие трансформации относительно тока?
Кроме того, если это не подразумевается, я использую OpenGL, GLSL, C ++ и GLM, так что примеры и объяснения в терминах этого очень ценятся, если не нужны.
Чем больше деталей, тем лучше!
Заранее спасибо.
источник
Матричные накопления могут фактически решить замок Gimbal. Накапливая повороты, вы добавляете подвески, позволяющие любое произвольное вращение. Диаграмма, которую предоставил ktodisco, показывает блокировку карданного подвеса на левой диаграмме. Матрица для этой ориентации может быть определена как:
Из-за вращения y-кардана X и Z-карданы теперь заблокированы, поэтому мы потеряли один градус движения. На данный момент у нас нет рыскания (локальный y, глобальный z) с использованием этих трех гимбалов. Но, добавив еще один кардан, я могу вращаться вокруг y:
Для каждого нового броска, тангажа и рыскания, просто добавьте другой кардан, накапливая их в одну матрицу. Таким образом, каждый раз, когда требуется другое локальное вращение, вращение создается и умножается на матрицу накопления. Как упоминается в главе, проблемы все еще существуют, но замок карданного подвеса не входит в их число.
источник