2008-11-25 13 views
14

Así que he escrito una cámara 3D basada en Quaternion orientada a nuevos programadores, por lo que es muy fácil para ellos integrarla y comenzar a usarla.¿Las cámaras 3D basadas en Quaternion deberían acumular Quaternion o ángulos de Euler?

Mientras lo desarrollaba, al principio tomaba la entrada del usuario como ángulos de Euler, luego generaba un Quaternion basado en la entrada de ese fotograma. 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 ejes impropios.

¿Alguno de los miembros de Stackoverflow tiene alguna idea de este problema? ¿Es esa una forma correcta de hacer las cosas?

Respuesta

12

La multiplicación de cuaterniones va a sufrir por la acumulación de problemas de redondeo de punto flotante (incluso ángulos simples como 45 grados no serán exactos). Es una excelente manera de realizar 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 recuperarlo, en cualquier caso, tendría que renormalizarse de nuevo a ángulos de Euler. Un ángulo de Euler de punto fijo no va a acumular redondeo.

El recálculo del cuaternión por fotograma 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.

+0

lo mismo aplica para el enfoque de matriz de transformación y no es demasiado esfuerzo agregar un contador de operaciones en la clase de cuaternión basada en el ángulo de Euler (solo algunas líneas). Por cierto, no recomiendo normalizar con demasiada frecuencia porque puede ensuciar un poco los efectos de transformación deseados. Normalmente normalizo cada operación de 64-128 – Spektre

+0

_ "para recuperar eso, tendrías que renormalizar de nuevo a ángulos de Euler en cualquier caso" _ - Esto no es cierto en absoluto - el factor de escala puede recuperarse tomando la magnitud del cuaternio – Eric

1

He visto a los dos defendidos. 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 recalcular sus cuaterniones por fotograma. ¿Tal vez sería mejor almacenar los últimos cuaterniones y marcarlos como sucios si tu marco recibe información?

+0

Así que tal vez almacene tanto los ángulos de Euler como los Quaternion, y solo actualice el Quaternion si necesita, o mejor aún, almacena la matriz de rotación, y solo la actualiza a través de un nuevo Quaternion si las cosas se actualizan. Sin embargo, esto es más importante para la rotación de los objetos, b/c la cámara cambiará con tanta frecuencia. – Adam

4

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: tienes tu código en funcionamiento, pero te das cuenta de que después de una cierta cantidad de navegación tu cámara se inclina molestamente, violando una invariante que no habías pensado de antemano. Efectivamente, se ha dado cuenta de que no desea querer para 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.

Lo malo es que los quateriones 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. De nuevo, es una pregunta de diseño de interfaz: necesita averiguar dónde necesitará los cuaterniones y cómo introducirlos y extraerlos ...

Cuestiones relacionadas