math - zyx - ¿Deberían las cámaras 3D basadas en Quaternion acumular Quaternion o ángulos de Euler?
matrices de rotacion (3)
He visto a los dos discutidos. Creo que la verdadera pregunta con la que tendrás que lidiar es la flexibilidad en tu sistema de cámara en el futuro; La orientación de IMO generalmente es más interesante en una vista en tercera persona (porque vas a rotar sobre el eje vertical del personaje). Si bien es posible que pueda "guiñar" alrededor de la vertical en vista en primera persona también, no estoy seguro de que sea realmente lo mismo.
Sin embargo, creo que es un desperdicio volver a calcular sus cuaterniones por cuadro. ¿Tal vez sería mejor almacenar los últimos cuaterniones y marcarlos como sucios si tu marco recibe información?
Así que he escrito una cámara 3D basada en Quaternion orientada a nuevos programadores, por lo que es muy fácil para ellos integrar y comenzar a usar.
Mientras lo desarrollaba, al principio tomaba la entrada del usuario como ángulos de Euler, luego generaba un Quaternion basado en la entrada de ese cuadro. Luego tomaría el Quaternion de la cámara y lo multiplicaría por el que generamos para la entrada, y en teoría eso debería simplemente agregar la rotación de la entrada al estado actual de la rotación de la cámara, y las cosas serían todo gordas y felices. Llamemos a esto: Acumulando Quaternions, porque estamos almacenando y agregando Quaternions solamente.
Pero noté que había un problema con este método. Cuanto más lo usaba, incluso si solo rotaba en un ángulo de Euler, decía Yaw, en algunas iteraciones comenzaría a sangrar en otro, digamos Pitch. Fue leve, pero bastante inaceptable.
Así que investigué un poco más y encontré un artículo que decía que era mejor acumular ángulos de Euler, por lo que la cámara almacena su rotación actual como ángulos de Euler, y la entrada simplemente se agrega a cada cuadro. Luego genero un Quaternion de cada cuadro, que a su vez se usa para generar mi matriz de rotación. Y esto solucionó el problema de la sangría de la rotación en los ejes incorrectos.
Entonces, ¿algún miembro de Stackoverflow tiene alguna idea de este problema? ¿Es esa una forma correcta de hacer las cosas?
Multiplicar los cuaterniones va a sufrir la acumulación de problemas de redondeo de coma flotante (incluso ángulos simples como 45 grados no serán exactos). Es una excelente manera de hacer rotaciones compuestas, pero la precisión de cada uno de los componentes del cuaternión va a disminuir con el tiempo. El sangrado es un efecto secundario, visualmente peor, aunque su cuaternión podría comenzar a incorporar un factor de escala; para recuperar eso, en cualquier caso, tendría que renormalizarse de nuevo a los ángulos de Euler. Un ángulo de Euler de punto fijo no va a acumular redondeo.
Recalcular el cuaternión por cuadro es mínimo. No me molestaría en tratar de optimizarlo. Probablemente puedas permitir que algunos cuaterniones se acumulen antes de renormalizarse para recuperar la precisión, pero realmente no vale la pena el esfuerzo.
La acumulación es un proceso inexacto. Al acumular muchas rotaciones incrementales se acumulará un error de redondeo ya sea que lo haga con cuaterniones o matrices.
Imagino algo como esto: pusiste tu código en funcionamiento, pero te diste cuenta de que después de una cierta cantidad de navegación tu cámara se inclinaba molesta, violando una invariante que no habías pensado de antemano. Efectivamente, te das cuenta de que no quieres acumular rotaciones; en cambio, quieres hacer otra cosa.
Puede ver esto como un problema de diseño de interfaz más que un problema de precisión numérica. Básicamente, la gente espera que la cámara navegue según el tono, la inclinación y el balanceo, por lo que elegir controlar y representar los ángulos directamente puede evitar muchos problemas.
El problema es que los quaterions parecen haberse vuelto redundantes (para este uso particular, al menos). Sin embargo, todavía quieres los cuaterniones: interpolar con los ángulos de cabeceo / guiñada / balanceo crudos puede ser feo. Una vez más, es una pregunta de diseño de interfaz: necesita averiguar dónde necesitará los cuaterniones y cómo hacerlos entrar y salir ...