Como Nathan Reed e teodron expuseram, a receita para rotacionar um vetor v por um quaternário de comprimento unitário q é:
1) Crie um quaternion puro p fora de v . Isso significa simplesmente adicionar uma quarta coordenada de 0:
p=(vx,vy,vz,0)⇔p=(v,0)
2) Pré-multiplique-o com q e pós-multiplique-o com o conjugado q * :
p′=q×p×q∗
3) Isso resultará em outro quaternion puro que pode ser retornado a um vetor:
v′=(p′x,p′y,p′z)
Este vector v′ é v girado por q .
Isso está funcionando, mas está longe de ser o ideal . Multiplicações de Quaternion significam toneladas e toneladas de operações. Fiquei curioso sobre várias implementações como esta e decidi descobrir de onde elas vieram. Aqui estão minhas descobertas.
Também podemos descrever q como a combinação de um vetor tridimensional u e um escalar s :
q=(ux,uy,uz,s)⇔q=(u,s)
Pelas regras de multiplicação de quaternion , e como o conjugado de um quaternion de comprimento de unidade é simplesmente inverso, obtemos:
p′=qpq∗=(u,s)(v,0)(−u,s)=(sv+u×v,−u⋅v)(−u,s)=((−u⋅v)(−u)+s(sv+u× v)+(sv+u×v)×(−u),…)=((u⋅v)u+s2v+s(u×v)+sv×(−u)+(u×v)×(−u),…)
A parte escalar (elipses) resulta em zero, conforme detalhado aqui . O interessante é a parte do vetor, também conhecido como vetor girado v ' . Pode ser simplificado usando algumas identidades vetoriais básicas :
v′=(u⋅v)u+s2v+s(u×v)+s(u×v)+u×(u×v)=(u⋅v)u+s2v+2s(u×v)+(u⋅v)u−(u⋅u)v=2(u⋅v)u+(s2−u⋅u)v+2s(u×v)
Agora isso é muito mais ideal ; dois produtos pontuais, um produto cruzado e alguns extras: cerca de metade das operações. O que daria algo parecido com isso no código-fonte (assumindo alguma biblioteca matemática vetorial genérica):
void rotate_vector_by_quaternion(const Vector3& v, const Quaternion& q, Vector3& vprime)
{
// Extract the vector part of the quaternion
Vector3 u(q.x, q.y, q.z);
// Extract the scalar part of the quaternion
float s = q.w;
// Do the math
vprime = 2.0f * dot(u, v) * u
+ (s*s - dot(u, u)) * v
+ 2.0f * s * cross(u, v);
}
vprime = v + ((cross(u, v) * s) + cross(u, cross(u, v)) * 2.0f
é uma otimização semelhante? Parece um pouco semelhante, mas não é o mesmo - ele usa apenas produtos cruzados, sem produtos pontuais. O código fonte original pode ser encontrado no arquivo type_quat.inl do repositório oficial do GLM, nooperator*
qual leva um quaternion e um vector (vec<3, T, Q> operator*(qua<T, Q> const& q, vec<3, T, Q> const& v)
)Primeiro de tudo, q ^ (- 1) não é -q / magnitude (q); é q * / (magnitude (q)) ^ 2 (q * é o conjugado; isso nega todos os componentes, exceto o real). Obviamente, você pode deixar de fora a divisão pela magnitude se todos os seus quaternions já estiverem normalizados, o que normalmente seria em um sistema de rotação.
Quanto à multiplicação com um vetor, você apenas estende o vetor a um quaternion definindo o componente real de um quat como zero e seus componentes ijk como xyz do vetor. Então você faz as multiplicações do quaternion para obter v 'e extrai os componentes ijk novamente. (A parte real de v 'sempre deve sair zero, mais ou menos algum erro de ponto flutuante.)
fonte
Primeira observação: o inverso de
q
não é-q/magnitude(q)
, isso é completamente errado. Rotações com quaterniões implicam que esses equivalentes de números complexos em 4D tenham norma unitária; portanto, residem na esfera unitária S3 nesse espaço 4D. O fato de um quat ser unitário significa que sua norma énorm(q)^2=q*conjugate(q)=1
e isso significa que o inverso do quat é seu conjugado.Se um quaternião unitário é escrito como
q=(w,x,y,z)
= (cos (t), sin (t) v ), então seu conjugado éconjugate(q)=(w,-x,-y,-z)
= (cos (t), - sin (t) v ), onde t é metade do ângulo de rotação e ev é o eixo de rotação (como um vetor unitário, é claro).Quando aquele cara de Hamilton decidiu brincar com equivalentes numéricos complexos em dimensões mais altas, ele também encontrou algumas boas propriedades. Por exemplo, se você emprega um quaternion completamente puro
q=(0,x,y,z)
(sem parte escalar w !), Pode considerar essa porcaria como um vetor (na verdade, é um quat do que as pessoas podem chamar de equador da esfera S3, que é uma esfera S2! ! - coisas preocupantes, se considerarmos o quão tecnicamente prejudicada as pessoas no século 19 nos parecem caçadores de olhos nos telefones hoje em dia). Então Hamilton pegou esse vetor em sua forma quat:v=(0,x,y,z)
e fez uma série de experimentos considerando as propriedades geométricas dos quats. Resumindo a história:Onde
Observação: o q * (0, v) * conj (q) deve ser outro quat da forma (0, v '). Não analisarei toda a explicação aparentemente complicada de por que isso acontece, mas se você girar um quaternário imaginário puro (ou um vetor no nosso caso!) Através desse método, deverá obter um tipo de objeto semelhante: quat imaginário puro. e você assume sua parte imaginária como resultado. Aí está, o maravilhoso mundo das rotações com quaternions em uma casca de noz (ty).
OBSERVAÇÃO : para quem se interessa por essa frase exagerada: os quats são bons porque os evitam o bloqueio do cardan ... devem desbloquear sua imaginação primeiro! Os quats são um mero aparato matemático "elegante" e podem ser evitados por meio de outras abordagens, a que acho completamente equivalente geometricamente sendo a abordagem do ângulo do eixo.
CÓDIGO : a biblioteca C ++ que eu imagino é bastante simplista, mas possui todas as operações de matriz, vetor e quat que um experimentalista de gráficos 3D deve precisar sem ter que perder mais de 15 minutos para aprendê-lo. Você pode testar as coisas que escrevi aqui usando esse em 15 minutos se você não é um novato em C ++. Boa sorte!
fonte
Aqui está uma maneira alternativa de transformar um vetor por um quaternion. É a maneira como a MS faz isso na estrutura xna. http://pastebin.com/fAFp6NnN
fonte
Eu tentei resolver isso manualmente, e criei a seguinte equação / método:
Eu gostaria que alguém olhasse sobre a derivação do mt que eu usei http://pastebin.com/8QHQqGbv. Eu sugiro que copie para um editor de texto que suporte rolagem lateral
na minha notação, usei q ^ (- 1) para significar conjugados, e não inversos, e identificadores diferentes, mas espero que sejam seguidos. Eu acho que a maioria está certa, especialmente onde provar a parte real do vetor desapareceria.
fonte