¿Cómo calcular el vector de una intercepción?

11

Dado que hay un espacio bidimensional, y 1 nave espacial amiga parada, un enemigo NO se mueve directamente a la nave amiga con posición, velocidad y dirección reales conocidas.

La nave amiga quiere entrar en el campo de tiro para luchar contra el enemigo.

En realidad, estoy configurando solo un vector directo a la posición real de la nave en movimiento, y lo recalculo cada cuadro, resultando en una especie de trayectoria de vuelo "redonda".

Lo que quiero es establecer un camino directo y directo a la posición que tendrá el enemigo (presumiblemente) cuando se alcance la distancia de disparo, suponiendo que el enemigo no cambiará de rumbo hasta entonces.

Como primera implementación "simple", sería suficiente si asumimos que el amigo puede acelerar de 0 a máximo en poco tiempo.

La implementación preferida sería aquella que considera las capacidades de aceleración del amigo y sabe cuándo la intercepción es imposible debido a la velocidad. Debería funcionar para cada velocidad de arranque, no solo desde parado. Una ventaja sería incluso si considera el frenado (luchar contra la velocidad de la luz es muy ineficiente en el universo dado)

NobbZ
fuente

Respuestas:

5

Si entiendo tu pregunta, no quieres que la nave se dirija hacia el objetivo, sino que vuele en línea recta para interceptar el objetivo. Estoy haciendo un juego de defensa de la torre que básicamente tiene la misma necesidad de la bala de una torre, una torre quiere disparar un arma de manera que la bala intercepte un objetivo en movimiento siempre que no cambie la velocidad / dirección. La forma en que lo resolví fue usando una ecuación cuadrática. Aquí hay un pseudocódigo:

Vector totarget =  target.position - tower.position;

float a = Vector.Dot(target.velocity, target.velocity) - (bullet.velocity * bullet.velocity);
float b = 2 * Vector.Dot(target.velocity, totarget);
float c = Vector.Dot(totarget, totarget);

float p = -b / (2 * a);
float q = (float)Math.Sqrt((b * b) - 4 * a * c) / (2 * a);

float t1 = p - q;
float t2 = p + q;
float t;

if (t1 > t2 && t2 > 0)
{
    t = t2;
}
else
{
    t = t1;
}

Vector aimSpot = target.position + target.velocity * t;
Vector bulletPath = aimSpot - tower.position;
float timeToImpact = bulletPath.Length() / bullet.speed;//speed must be in units per second

Encontré que esto funcionaba tan bien que no necesitaba detección de colisión para el disparo ... Pude contar con que cada disparo golpeara un ojo de buey, independientemente de la distancia / dirección / velocidad del objetivo, siempre que esos factores permanecieran constantes.

Steve H
fuente
Según su descripción, esto parece ser lo que estoy buscando, al menos la forma más fácil, suponiendo una aceleración instantánea a la velocidad máxima. Echaré un vistazo más de cerca por la noche. ¿Estoy asumiendo que Vector.Dot devuelve el producto punto de los vectores?
NobbZ
Hmmm ... He hecho esto en rubí ahora, pero parece que algo anda mal. Cada vez que lo intento, se produce una excepción, porque la expresión en el sqrt se evalúa como algo negativo y, por lo tanto, está fuera de los límites. ¿Cómo puedo manejar esto? Perdón por la pregunta, pero solo puedo usar esto, pero no entiendo los detalles aquí hasta que alguien me dé un consejo.
NobbZ
El ejemplo fue de este libro: amazon.com/…
Steve H
1
No sé si esto ayuda, pero aquí hay un código de Python que logra lo mismo. moddb.com/mods/wicmw/tutorials/…
Steve H
De acuerdo, todavía no entiendo las matemáticas del agujero detrás, pero gracias al código de Python, la documentación me dijo que si hay un valor negativo dentro del sqrt, entonces mi amigo es lento para ponerse al día. Después de ajustar mis valores de prueba obtengo algunos resultados. Gracias por tu ayuda.
NobbZ
6

Le sugiero que analice los comportamientos de dirección. Especialmente persecución . El código fuente se puede encontrar en la implementación de OpenSteer o buscar un libro como " Programando IA del juego por ejemplo " (ISBN 13: 978-1556220784)

bummzack
fuente
la búsqueda parece necesitar conocimiento sobre el objetivo y se dirige hacia eso, pero en realidad no sé el objetivo. Sé dónde está el enemigo ahora, sé su velocidad y su dirección. Ahora quiero saber en qué dirección debe ir para interceptar al enemigo en su camino hacia su objetivo lo más rápido y rápido posible. Como se mencionó antes, la aceleración puede ignorarse al principio, esto incluso ahorraría mucho tiempo de procesamiento en comparación con la versión real ... Con el nuevo modelo, tengo que volver a calcular solo cuando el enemigo dispara un evento de "cambio de rumbo", no para cada " ha movido "-evento como lo hago ahora.
NobbZ
Sí, lo que describe es persecución. No conoce el objetivo ... hace una predicción basada en la ubicación, velocidad y dirección actuales de los "enemigos"
bummzack
Entonces he entendido mal la descripción, la examinaré más de cerca mañana.
NobbZ
Acabo de terminar de leer el documento hace unos minutos, la búsqueda NO es lo que estoy buscando. Es como mi implementación real, excepto que apunta a la posición del siguiente cuadro, todavía tengo que volver a calcular el nuevo curso en cada cuadro y el curso está resultando en una curva. Pero lo que quiero es la línea directa suponiendo que el enemigo no cambia la velocidad o el rumbo hasta que ambos se encuentran. Si todavía no está lo suficientemente claro, trato de dibujar lo que quiero después del trabajo. Pero gracias por los enlaces de todos modos. Creo que puedo usar esto en otro lugar del proyecto.
NobbZ
@NobbZ Lo siento, mi respuesta no fue útil. Tal vez debería editar su pregunta en consecuencia, porque declaraciones como: "Lo sé, que en caso de cambio de velocidad o curso del enemigo, cada cálculo debe repetirse" puede ser engañoso ... si lo hiciera, terminaría teniendo el comportamiento de dirección de "persecución".
bummzack