Pregunta

Así que escribí una cámara 3D basada en Quaternion orientada hacia nuevos programadores, por lo que es muy fácil para ellos integrarse y comenzar a usarla.

Mientras lo estaba desarrollando, al principio tomaría la entrada del usuario como ángulos de Euler, luego generaría un Quaternion basado en la entrada para ese marco. 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 simplemente agregaría la rotación de entrada al estado actual de la rotación de la cámara, y las cosas serían muy gordas y felices. Llamemos a esto: Acumulación de Cuaterniones, porque solo estamos almacenando y agregando Cuaterniones.

Pero noté que había un problema con este método. Cuanto más lo usaba, incluso si solo estaba girando en un ángulo de Euler, digamos Yaw, en algunas iteraciones comenzaría a desangrarse 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 a partir de ellos cada cuadro, que a su vez se utiliza para generar mi matriz de rotación. Y esto solucionó el problema de la rotación sangrando en ejes inadecuados.

Entonces, ¿algún miembro de Stackoverflow tiene alguna idea de este problema? ¿Es esa una forma adecuada de hacer las cosas?

¿Fue útil?

Solución

Multiplicar cuaterniones sufrirá la acumulación de problemas de redondeo de punto flotante (incluso los á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 de su cuaternión disminuirá con el tiempo. El sangrado es uno de los efectos secundarios, aunque visualmente peor es que su cuaternión podría comenzar a incorporar un factor de escala: para recuperar eso, tendría que volver a normalizar de nuevo a los ángulos de Euler en cualquier caso. 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 podría permitir que se acumulen algunos cuaterniones antes de volver a formalizar para recuperar la precisión, pero realmente no vale la pena el esfuerzo.

Otros consejos

La acumulación es un proceso inexacto. La acumulación de muchas rotaciones incrementales acumulará un error de redondeo, ya sea que lo haga con cuaterniones o matrices.

Me imagino algo como esto: tienes tu código en funcionamiento, pero notaste que después de cierta navegación, tu cámara se estaba volviendo molesta, violando una invariante que no habías pensado de antemano. Efectivamente, te has dado cuenta de que no quieres acumular rotaciones; en cambio quieres hacer otra cosa.

Puede ver esto como más un problema de diseño de interfaz que un problema de precisión numérica. Básicamente, las personas esperan que una cámara navegue de acuerdo con el cabeceo, la guiñada y el giro, por lo que elegir controlar y representar los ángulos directamente puede evitar muchos problemas.

Lo malo aquí es que los quaterions parecen haberse vuelto redundantes (al menos para este uso en particular). Sin embargo, todavía desea los cuaterniones: la interpolación con los ángulos de cabeceo / guiñada / balanceo puede ser fea. Una vez más, es una pregunta de diseño de interfaz: debe averiguar dónde necesitará los cuaterniones y cómo introducirlos y extraerlos ...

He visto a ambos discutidos. Creo que la verdadera pregunta con la que tendrá que lidiar es la flexibilidad en el sistema de su cámara en el futuro; IMO guiñada es generalmente más interesante en una vista en tercera persona (porque vas a rotar sobre el eje vertical del personaje). Si bien se puede decir "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. ¿Quizás sería mejor almacenar los últimos cuaterniones y marcarlos como sucios si su marco recibe información?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top