Translação E Rotação - Bioconectados - MOVIMENTOS DA TERRA: ROTAÇÃO E TRANSLAÇÃO
Bioconectados - MOVIMENTOS DA TERRA: ROTAÇÃO E TRANSLAÇÃO

A ordem que todo mundo erra na primeira vez

Quando você monta uma cena ou um modelo, costuma pensar em translação e rotação como duas coisas separadas. Elas são. Mas o jeito como o motor ou o software as aplica muda completamente o resultado final, e se você não entender isso, vai passar horas corrigindo posições que não fazem sentido. A rotação é aplicada primeiro ao objeto local, depois a translação move esse objeto pelo espaço do mundo. Isso significa que rotacionar algo antes de transladar vai dar um resultado completamente diferente de fazer o inverso. A maioria dos principiantes vê um pivô girando errado e culpa o rig, o script ou o artista. Na verdade, é só a ordem das operações que está errada.

Como funciona translação e rotação na prática

Vamos começar com um exemplo simples. Você tem um braço robótico ou um boneco 3D e quer posicionar a mão dele em coordenadas específicas do espaço. Se você apenas transladar a mão sem considerar a rotação dos cotovelos e ombros, ela vai chegar no lugar certo mas com o orientamento errado. Se rotacionar os joints antes de transladar o efetuador, o ponto final vai acabar em outro lugar completamente. Isso acontece porque cada transformação depende da anterior. O problema mais comum que eu vejo é com sistemas de IK. O usuário define um target para a mão e o sistema resolve os ângulos dos joints. Funciona bem até você tentar combinar isso com uma rotação manual do pulso. Aí o target some, o braço distorce, e o artista fica olhando para a tela sem entender nada. O motivo é simples: o IK resolve posições no espaço global, mas a rotação manual do pulso muda o referencial local do efetuador. A solução mais rápida é aplicar a rotação do pulso como um offset no espaço local do IK end effector, não no mundo.

Eu trabalhei num projeto onde o cliente queria que um veículo seguisse um caminho curvo mas mantivesse o eixo traseiro alinhado com a tangente da curva. A abordagem ingênua seria calcular a rotação e a translação separadamente a cada frame. O que funcionou foi usar um sistema de transformações encadeadas: primeiro a translação ao longo do path, depois a rotação baseada no vetor tangente, e por último um offset local para o eixo traseiro. O resultado foi suave e previsível, e levou cerca de três horas para implementar, contra dois dias de tentativa e erro na abordagem anterior. Um detalhe que pouca gente leva a sério é o tema de gimb lock. Quando você usa euler angles para rotação, existe uma configuração em que dois eixos se alinham e você perde um grau de liberdade. Não é um bug do software, é uma limitação matemática. A alternativa são quaternions, que evitam o problema mas trazem outros: são menos intuitivos de manipular diretamente e exigem conversão constante para euler angles na hora de ler os valores num viewport. Eu recomendo usar quaternions internamente no código e converter para euler apenas na interface do usuário.

👉 Clique no botão abaixo para saber mais sobre o assunto!

Outro ponto que causa confusão é a diferença entre rotação local e rotação global. Um objeto pode estar rotacionado 30 graus em torno do eixo Y local, o que pode ser equivalente a uma combinação de rotações em X, Y e Z no espaço global. Quando você lê os valores num editor, eles quase sempre mostram a representação euler local. Se você precisa saber a orientação real no mundo, tem que multiplicar a matriz de rotação local pela matriz de transformação pai. Faça isso manualmente se o seu engine não oferecer uma função pronta. Translação também tem suas armadilhas. O systema de coordenadas do engine importa muito. Alguns usam Y como up, outros Z. Alguns são left-handed, outros right-handed. Trocar de engine sem ajustar essas convenções pode fazer com que a translação em Y suba quando deveria descer, ou que a rotação em X inverta o sentido. Eu perdi uma tarde inteira numa migração porque o novo engine inverteu o eixo Z sem avisar no changelog.

Se você está montando algo do zero, considere usar uma biblioteca de transformações estabelecida em vez de escrever suas próprias funções de matriz. OpenGL Math, GLM, Unity Mathf — qualquer uma dessas lida com os casos de borda que você não pensa até acontecer. Escrever sua própria rotina de multiplicação de matriz parece econômico no começo, mas na hora que você precisa de slerp entre rotações ou de normalizar quaternions, vai gastar mais tempo do que se tivesse usado a biblioteca desde o início. Aqui vai um exemplo prático de como estruturar o código. Para aplicar ambas as transformações corretamente, você constrói uma matriz de rotação a partir dos ângulos desejados, uma matriz de translação a partir das coordenadas, e multiplica na ordem correta: matriz_final = translação * rotação * posição_original. A ordem dos fatores na multiplicação é crítica. Inverter translação e rotação dá um resultado diferente, e não adianta só testar visualmente — tem que entender porquê.

Para debugar problemas de transformação, coloque um gizmo de eixos XYZ no ponto que você espera que o objeto vá parar. Se o gizmo não alinhhar com a orientação esperada, o erro está na rotação. Se o gizmo estiver orientado corretamente mas fora do lugar, o erro está na translação. Se ambos estiverem errados, verifique se as transformações dos pais estão interferindo. Esse método economiza bastante tempo comparado a inspecionar os valores numéricos um por um. Em resumo, translação e rotação são operações fundamentais que parecem simples até você se deparar com um caso real. A ordem importa, o sistema de coordenadas importa, e a representação da rotação importa. Entender esses três fatores evita a maior parte dos problemas que aparecem no dia a dia.