Movimiento de proyectil - Flecha

13

En un juego 2D, simplemente quiero dibujar la trayectoria de una flecha en vuelo. Con el siguiente código, la trayectoria (la parábola) se ve bien, pero el ángulo (o rotación) o la flecha no.

float g = -9.8f;
float x = (launchVelocity * time);
float y = (launchVelocity * time) + (0.5f * g * (float)Math.Pow(time, 2));
float angle = (float)Math.Tanh(y / x);

¿Qué me estoy perdiendo? Gracias.

Martín
fuente
3
Una captura de pantalla puede ayudar
doppelgreener

Respuestas:

10

Arctanhte da la tangente para la curva hiperbólica! Que yo sepa, tu parábola no es una hipérbola.

Pero tenemos buenas noticias: encontrar la tangente para su parábola es más fácil. La ecuación es

x = s · t => t = x / s; y = s · t + g / 2 · t² => y = x + g / 2 · x² / s²

¿Dónde está tu launchVelocity? Ahora la pendiente de tu flecha es:

∂y / ∂y = g / (2s²) · x + 1

Puede usarlo Arctanahora con seguridad si lo desea

Alguna información adicional sobre física:

La trayectoria aproximada que está simulando se aplica al centro de masa de su flecha. Cuando dices "posición" (x, y) estás hablando de la posición del centro de masa. El centro de masa de una flecha está ligeramente hacia adelante desde el punto medio y debe tenerlo en cuenta si va a dibujar la flecha.

Tenga en cuenta que no está considerando el momento de inercia de la flecha (que puede variar mucho si dispara una ballesta gigante) y no está considerando la dinámica de fluidos de la flecha: ¡el vuelo de la flecha del arco no seguirá un camino parabólico!

FxIII
fuente
Gracias Fxlll ¿Alguna idea de dónde podría obtener las fórmulas que se aplican a la física de una flecha?
Martin
Creo que te refieres a:! [& Parte; y / & parte; x = g / (2s & sup2;) & middot; x + 1] [2] pero en cualquier caso creo que recomendé un mejor enfoque a continuación. Por un lado, no explicaste sobre la separación de los componentes x e y, por lo que esto está codificado en un ángulo arbitrario de 45 grados, con launchVelocity no es realmente launchVelocity, sino el componente en x e y
Dov
Uno puede calcular los momentos de inercia con facilidad. Estas son dos para barras, una para la rotación alrededor de su centro de masa y la otra para la rotación alrededor del eje de la barra. El principio de superposición se aplica para momentos de inercia, por lo que la flecha se puede dividir en tres partes: plumas, cuerpo y punta.
FxIII
1
El problema es que el único impulso es fácil de calcular debido a la variación del ángulo (puede ver que derivando dos veces una parábola solo queda un término constante). El otro es causado por el giro debido a la pluma posterior. Aquí, los arrastres de plumas y la fricción están involucrados, convirtiendo la energía cinética en spinning, ralentizando la flecha pero agregando efecto giroscópico. Esto influye en la trayectoria y es bastante difícil de modelar
FxIII
De todos modos, si puede relacionar el impulso con la velocidad dada una configuración de plumas, todo se puede calcular mediante una integración completa, pero no estoy seguro de que pueda tener una forma cerrada para las ecuaciones de movimiento (es decir, puede obtener un algoritmo de integración pero no un parámetro) ecuación).
FxIII
4

Desea el ángulo de la flecha en cualquier momento. Recordaste que para calcular un ángulo, hay una tangente. Pero aquí es donde su pensamiento comenzó a salir mal:

  1. Lo que quiere es delta y / delta x, porque la pendiente es la tasa de cambio (mencionado en una de las otras respuestas). Tenga en cuenta que x es solo la posición en la que se encuentra en cualquier momento, no dx.

Ok, entonces si descuidas la fricción del aire, entonces la velocidad x de la flecha es constante.

Primero, descomponga la velocidad en componentes x e y. Podría disparar en un ángulo de 45 grados o 60 grados. Por lo tanto, necesita launchVelocity y un ángulo, no es escalar.

Segundo, calcule todo como doble, no como flotante. No eres lo suficientemente sofisticado numéricamente para saber cuándo el error de redondeo no te matará, así que no lo intentes. No es un gran ahorro de tiempo en ningún caso.

Tercero, no use Math.pow, es lento y no es tan preciso como multiplicar por potencias enteras. También puede ahorrar mucho tiempo utilizando el formulario de Horner (ver más abajo)

final double DEG2RAD = Math.PI/180;
double ang = launchAngle * DEG2RAD;
double v0x = launchVelocity * cos(ang); // initial velocity in x
double v0y = launchVelocity * sin(ang); // initial velocity in y

double x = (v0x * time);
// double y = (v0y * time) + (0.5 * g * (float)Math.Pow(time, 2));
double y = (0.5 * g * time + v0y) * time

Si está desesperado por el rendimiento, incluso puede calcular previamente 0.5 * g, pero el código anterior lo llevará al 90% del camino sin hacer nada demasiado loco. Benchmark haciendo esto 10 millones de veces si lo desea, ciertamente no es una gran cantidad de tiempo, pero en términos de porcentaje es bastante grande: las bibliotecas son muy lentas en Java

Entonces, si querías el ángulo en el que debe ir la flecha, lo que quieres es

atan(dy/dx)

Y en este caso, eso funcionaría porque dx es una constante. Pero en general, dx puede ser cero, por lo que generalmente desea usar:

atan2(dy, dx)

que es una función específicamente diseñada para este trabajo.

Pero como dije, las funciones de la biblioteca en Java son horriblemente lentas, y en este caso hay una mejor manera de hacerlo sin lo mencionado anteriormente por @FxIII.

Si la velocidad horizontal es siempre v0x, y la velocidad vertical es:

double vy = v0y - 0.5 * g * time;

entonces su delta es: vx, vy

No necesitas el ángulo. Si desea dibujar una flecha, use algo nominalmente como:

plot (x, y, x + vx, y + vy);

No sé qué estás dibujando, así que si necesitas el ángulo para rotarlo (como si estuvieras usando JOGL), entonces seguro, usa el ángulo.

No olvide si está usando opengl para volver a convertir el ángulo en grados, porque ATAN2 devuelve radianes:

final double RAD2DEG = 180 / Math.PI;
double ang = Math.atan2(vy,vx); // don't forget, vy first!!!
double deg = ang * RAD2DEG;
Dov
fuente
2

Tanh () ( tangente hiperbólica ) toma un ángulo como parámetro, pero le has dado la relación de los lados.

Lo que realmente quieres es usar el arcotangente hiperbólico , que toma la relación de los lados como parámetro y devuelve el ángulo. (Nombrar esto puede ser "atanh", "atanh2", "arctanh" o algo similar; parece variar mucho entre las diferentes bibliotecas de matemáticas)

Trevor Powell
fuente
No, no quieres nada hiperbólico
Dov
Gah, tienes toda la razón. Inmediatamente me di cuenta del error "uso de trigonometría básica", y me percaté de que la función que estaba usando era completamente incorrecta para el resto de su enfoque.
Trevor Powell
Tan () toma un ángulo. Atan toma una relación del lado del triángulo (sin / cos).
3Dave