Cómo hacer que una flecha caiga en una posición específica en el espacio mundial 3D

8

En mi juego cuando hago clic con el mouse en el terreno en algún lugar, me gustaría que el jugador dispare una flecha a esa posición de forma parabólica.

La flecha tiene una posición, aceleración y velocidad, todo utilizando vectores 3D. Miré la trayectoria de un artículo sobre proyectiles en wikipedia, pero no sé cómo aplicarlo en mi situación, ya que explica las matemáticas 2D. Me preguntaba si hay una solución para los vectores 3D. ¿Algún buen recurso relacionado con la situación 3D?

Mella
fuente
55
No escribiré esto como respuesta, ya que espero que alguien pueda dar una respuesta más completa, pero puedes usar la solución 2D en 3D. La solución 2D se aplica al plano vertical que atraviesa el punto inicial y final, por lo que toma la solución 2D y la gira para que coincida con ese plano en el espacio 3D.
Kylotan

Respuestas:

12

Para ampliar el comentario de Kylotan, puede usar las fórmulas 2D en 3D. Asumiendo que Y está arriba:

calcule la posición del objetivo en el espacio X'Y'Z ', donde el eje X' es paralelo a la dirección de vuelo de la flecha, el eje Y 'está arriba y Z' es perpendicular a los ejes X 'e Y'.

diagrama

Una vez que haya calculado X 'e Y', puede volver a convertir al espacio XYZ real

Ejemplo

Un arquero está en (1,0,1). Quiere disparar una flecha a (4,0,5). Consideramos que X 'es el vector unitario (0.6, 0, 0.8) ya que apunta directamente desde el origen al punto de destino. Luego consideramos que Z 'es (-0.8, 0, 0.6) porque es una perpendicular, pero como la flecha no se mueve en el eje Z', la ignoraremos. Su problema ahora es descubrir cómo disparar una flecha de (0,0) a (0,5) en el espacio X'Y '.

.. hacer cálculos 2D aquí. Tenga en cuenta que probablemente querrá funciones paramétricas de X 'e Y' en términos de t , la variable de tiempo.

Una forma de abstraer la conversión entre las dos coordenadas es usar una matriz de transformación.

let archer = Vector3d(1.0,0.0,1.0)
let target = Vector3d(4.0,0.0,5.0)
let travel = target - archer
let transform = Matrix4d.CreateTranslation(-archer) *
                Matrix4d.CreateRotationY(Math.Atan2(travel.Z,travel.X)) 
Vector3d.Transform(archer, transform) // transforms archer to (0,0,0)
Vector3d.Transform(target, transform) // transforms target to (5,0,0)

Cuando volvemos a convertir de X'Y'Z ' a XYZ , esto es simplemente una transformación lineal inversa.

let inverse = Matrix4d.Invert(transform)
Vector3d.Transform(Vector3d.Zero, transform) // transforms (0,0,0) to (1,0,1)
Palanqueta
fuente
¡Gracias, logré hacerlo funcionar! Todavía estoy descubriendo cómo hacerlo funcionar con diferentes alturas ahora ... :)
Nick
Nooooo! Erm. Esto se puede resolver analíticamente en cualquier dimensión sin recurrir al cambio de coordenadas o trigonometría. Vea ¿Cómo dar cuenta de la aceleración cuando apunta proyectiles? y playtechs.blogspot.com/2007/04/aiming-at-moving-target.html para ver ejemplos.
Electro