Estou lendo o livro on-line "Learning Modern 3D Graphics Programming" de Jason L. McKesson
A partir de agora, estou pronto para o problema do bloqueio do cardan e como resolvê-lo usando quaterniões.
No entanto, aqui mesmo, na página Quaternions .
Parte do problema é que estamos tentando armazenar uma orientação como uma série de três rotações axiais acumuladas. Orientações são orientações, não rotações. E as orientações certamente não são uma série de rotações. Portanto, precisamos tratar a orientação do navio como uma orientação, como uma quantidade específica.
Acho que esse é o primeiro ponto em que começo a ficar confuso, o motivo é que não vejo a diferença dramática entre orientações e rotações. Também não entendo por que uma orientação não pode ser representada por uma série de rotações ...
Além disso:
O primeiro pensamento nesse sentido seria manter a orientação como uma matriz. Quando chega a hora de modificar a orientação, simplesmente aplicamos uma transformação a essa matriz, armazenando o resultado como a nova orientação atual.
Isso significa que cada guinada, inclinação e rotação aplicada à orientação atual serão relativas a essa orientação atual. Qual é precisamente o que precisamos. Se o usuário aplicar uma guinada positiva, você deverá girá-la em relação ao ponto em que está apontando atualmente, e não em relação a algum sistema de coordenadas fixo.
Entendo o conceito, mas não entendo como se acumular transformações de matriz é uma solução para esse problema, como o código fornecido na página anterior não é apenas isso.
Aqui está o código:
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();
}
Na minha opinião, o que ele está fazendo (modificar uma matriz em uma pilha) é considerado acumular matrizes, já que o autor combinou todas as transformações de rotação individuais em uma matriz que está sendo armazenada no topo da pilha.
Minha compreensão de uma matriz é que elas são usadas para pegar um ponto que é relativo a uma origem (digamos ... o modelo) e torná-lo relativo a outra origem (a câmera). Tenho certeza de que essa é uma definição segura, no entanto, sinto que falta algo que está me impedindo de entender esse problema de bloqueio do cardan.
Uma coisa que não faz sentido para mim é: se uma matriz determina a diferença relativa entre dois "espaços", como é que uma rotação em torno do eixo Y para, digamos, rolar, não coloca o ponto no "espaço do rolo" "que pode ser transformado mais uma vez em relação a este rolo ... Em outras palavras, nenhuma outra transformação nesse ponto deve ser em relação a esse novo" espaço de rolo "e, portanto, não deve ter a rotação relativa ao anterior" modelo de espaço "que está causando o bloqueio do cardan.
É por isso que o bloqueio do cardan ocorre certo? É porque estamos girando o objeto em torno dos eixos X, Y e Z em vez de girar o objeto em torno de seus próprios eixos relativos . Ou eu estou errado?
Como aparentemente esse código no qual eu vinculei não é um acúmulo de transformações de matriz, você pode dar um exemplo de solução usando este método.
Então, em resumo:
- Qual é a diferença entre uma rotação e uma orientação?
- Por que o código está vinculado não é um exemplo de acumulação de transformações de matriz?
- Qual é o real e específico objetivo de uma matriz, se eu entendi errado?
- Como uma solução para o problema do bloqueio do cardan pode ser implementada usando o acúmulo de transformações matriciais?
- Além disso, como um bônus: por que as transformações após a rotação ainda são relativas ao "espaço do modelo?"
- Outro bônus: estou errado ao supor que, após uma transformação, novas transformações ocorrerão em relação à corrente?
Além disso, se não estava implícito, estou usando OpenGL, GLSL, C ++ e GLM, portanto, exemplos e explicações em termos destes são muito apreciados, se não for necessário.
Quanto mais os detalhes, melhor!
Desde já, obrigado.
fonte
As acumulações de matrizes podem, de fato, resolver o bloqueio do cardan. Ao acumular rotações, você adiciona cardan, permitindo qualquer rotação arbitrária. O diagrama fornecido pela ktodisco mostra uma trava de cardan no diagrama esquerdo. A matriz para esta orientação pode ser definida como:
Devido à rotação do cardan y, os cardan X e Z agora estão bloqueados, então perdemos um grau de movimento. Neste ponto, não temos guinada (y local, z global) usando esses três cardan. Mas adicionando outro cardan, eu posso girar localmente em torno do y:
Para cada novo lançamento, inclinação e guinada, basta adicionar outro cardan, ACUMULANDO-os em uma matriz. Portanto, toda vez que é necessária outra rotação local, uma rotação é criada e multiplicada para a matriz de acumulação. Como o capítulo menciona, ainda existem problemas, mas o bloqueio do cardan não é um deles.
fonte