Pregunta

Tengo un objeto de proyectil que se mueve a lo largo de un vector de velocidad. Necesito asegurarme de que el objeto siempre esté orientado en la dirección del vector de velocidad. Además, estoy representando la rotación de objetos utilizando cuaterniones, no matrices.

Sé que el primer paso es encontrar una base ortogonal:

forward = direction of velocity vector
up = vector.new(0, 1, 0)
right = cross(up, forward) 
up = cross(forward, right)

¿Cómo puedo convertir la base en un cuaternión de rotación?

Solución

Nota, me gustaría darle crédito a Noel Hughes por proporcionar la respuesta, pero quiero aclarar con mis propias experiencias. Sigue pseudocódigo:

   vec3 vel = direction of velocity vector
   vec3 forward = (1, 0, 0)  // Depends on direction your model faces. See below.
   vec3 axis = cross(forward, vel)
   if (axis == 0) then quit // Already facing the right direction!
   axis = normalize(axis)
   float theta = acos(vel.x/sqrt(vel.x^2, vel.y^2, vel.z^2))
   quat result = (0, axis.y * sin(theta/2), axis.z * sin(theta/2), cos(theta/2)

El último elemento del cuaternión es la parte escalar, los tres primeros elementos son las partes imaginarias. Además, el pseudocódigo anterior asume que su objeto en " espacio de modelo " puntos hacia abajo del eje x positivo. En mi caso, el objeto apuntó realmente hacia el eje y positivo, en cuyo caso hice los siguientes cambios:

   vec3 vel = direction of velocity vector
   vec3 forward = (0, 1, 0)  // Note that y-component is now 1
   vec3 axis = cross(forward, vel)
   if (axis == 0) then quit 
   axis = normalize(axis)
   float theta = acos(vel.x/sqrt(vel.x^2, vel.y^2, vel.z^2))
   quat result = (axis.x * sin(theta/2), 0, axis.z * sin(theta/2), cos(theta/2)
   // Note that SECOND component above is now 0
¿Fue útil?

Solución

Supongo que no te importa la orientación de tu proyectil, aparte de tener el eje longitudinal alineado con el vector de velocidad, y que el eje longitudinal es el eje x de (1, 0, 0).

Estás en el camino correcto. Normalice el vector de velocidad, (vx, vy, vz) / sqrt (vx ^ 2 + vy ^ 2 + vz ^ 2) cruce el eje x con él y normalice el resultado - (0, yn, zn) - esta es la rotación Eje para el cuaternion. El ángulo de rotación es simplemente theta = coseno inverso de vx / sqrt (vx ^ 2 + vy ^ 2 + vz ^ 2). El cuaternión resultante es entonces

(0, yn, zn) sn (theta / 2) cos (theta / 2)

Hazme saber si tienes alguna pregunta.

Noel Hughes nhughes1ster@gmail.com

Otros consejos

Me gustaría ver biblioteca vecmath (Java). Ha existido por mucho tiempo y lo usamos en nuestra comunidad. Se basa en 4 tuples y me sentiría decepcionado si no hubiera métodos sencillos para la transformación.

También escribiría pruebas de unidad para los resultados esperados. Es muy fácil confundir los marcos positivos y negativos, zurdos y diestros, y de movimiento / referencia. Comience con los simples (por ejemplo, xyz) para asegurarse de que tiene la respuesta correcta.

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