Come calcolare il vettore di un'intercettazione?


11

Dato che sono uno spazio bidimensionale e 1 nave spaziale amica ferma, un nemico NON si sta muovendo direttamente sulla nave amica con posizione, velocità e direzione effettive conosciute.

La nave amica vuole mettersi a sparare per combattere il nemico.

In realtà sto impostando solo un vettore diretto sulla posizione della nave in movimento, e ricalcolo ogni fotogramma, risultando in una sorta di percorso di volo "rotondo".

Quello che voglio è impostare un percorso diretto e diretto verso la posizione che il nemico avrà (presumibilmente) quando sarà raggiunta la distanza di tiro, supponendo che il nemico non cambierà rotta fino ad allora.

Come prima e "semplice" implementazione sarebbe sufficiente se assumessimo che l'amico possa accelerare da 0 a max in pochissimo tempo.

L'implementazione preferita sarebbe quella che considera le capacità di accelerazione dell'amico e sa quando l'intercettazione è impossibile a causa della velocità. Dovrebbe funzionare per ogni velocità iniziale, non solo da fermo. Un vantaggio sarebbe se considera anche la frenata (la lotta alla velocità della luce è molto inefficiente dal punto di vista energetico nell'universo dato)

Risposte:


5

Se capisco la tua domanda, non vuoi che la nave si diriga verso il bersaglio, ma piuttosto voli in linea retta per intercettare il bersaglio. Sto realizzando un gioco di difesa della torre che fondamentalmente ha lo stesso bisogno di un proiettile di una torre, una torre vuole sparare con una pistola in modo tale che il proiettile intercetti un bersaglio in movimento finché non cambia velocità / direzione. Il modo in cui l'ho risolto è stato usando un'equazione quadratica. Ecco qualche pseudo codice:

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

Ho scoperto che funziona così bene che non ho avuto bisogno del rilevamento delle collisioni per il tiro ... Sono stato in grado di contare su ogni colpo colpendo un occhio di bue, indipendentemente dalla distanza / direzione / velocità del bersaglio, purché quei fattori rimanessero costanti.


Dalla tua descrizione questo sembra essere quello che sto cercando, almeno nel modo più semplice ipotizzando un'accelerazione istantanea alla massima velocità. Lo guarderò più da vicino questa sera. Sto assumendo bene che Vector.Dot restituisce il dotproduct di the ai vettori?
NobbZ,

Hmmm ... L'ho fatto in ruby ​​ora, ma sembra che ci sia qualcosa di sbagliato. Ogni volta che provo, viene generata un'eccezione, poiché l'espressione in sqrt restituisce qualcosa di negativo e quindi fuori dai limiti. Come posso gestirlo. Ci scusiamo per la domanda, ma posso solo usarlo, ma non capisco i concetti qui finché qualcuno non mi dà un consiglio.
NobbZ,

L'esempio è tratto da questo libro: amazon.com/…
Steve H

1
non so se questo aiuta, ma ecco un po 'di codice Python che realizza la stessa cosa. moddb.com/mods/wicmw/tutorials/…
Steve H

OK, non capisco ancora la buca matematica dietro, ma grazie per il codice Python, la documentazione mi ha detto che se c'è un valore negativo all'interno di sqrt, allora il mio amico deve rallentare per recuperare. Dopo aver modificato i miei valori di test ottengo alcuni risultati. Grazie per il vostro aiuto.
NobbZ,

6

Ti suggerisco di esaminare i comportamenti di guida. Soprattutto ricerca . Il codice sorgente può essere trovato nell'implementazione di OpenSteer o cercare un libro come " Programmare l'intelligenza artificiale del gioco con l'esempio " (ISBN 13: 978-1556220784)


la ricerca sembra aver bisogno della conoscenza dell'obiettivo e si dirige verso quello, ma non conosco davvero l'obiettivo. Ora so dove si trova il nemico, conosco la sua velocità e la sua direzione. Ora voglio sapere in quale direzione deve andare per intercettare il nemico sulla sua strada verso il suo obiettivo il più presto e velocemente possibile. Come accennato prima, l'accelerazione può essere inizialmente ignorata, ciò consentirebbe anche di risparmiare molto tempo di elaborazione rispetto alla versione attuale ... Con il nuovo modello devo ricalcolare solo quando il nemico spara un evento "coursechange", non per tutti " hasmoved "-event come lo faccio ora.
NobbZ,

Sì, quello che descrivi è la ricerca. Non conosce il bersaglio .. fa una previsione basata sulla posizione, sulla velocità e sulla direzione attuali dei "nemici"
bummzack,

Poi ho capito male la descrizione, lo guarderò più da vicino domani.
NobbZ,

Ho appena finito di leggere il documento qualche minuto fa, l'inseguimento NON è quello che sto cercando. È come la mia effettiva implementazione, tranne per il fatto che ha come obiettivo la posizione del frame successivo, devo ancora ricalcolare il nuovo corso in ogni frame e il corso sta risultando in qualche curva. Ma quello che voglio è la linea diretta supponendo che il nemico non cambi velocità o rotta finché entrambi non si incontrano. Se questo non è ancora abbastanza chiaro, provo a disegnare quello che voglio dopo il lavoro. Ma grazie per i collegamenti comunque. Penso di poterlo usare da qualche altra parte nel progetto.
NobbZ,

@NobbZ Mi dispiace che la mia risposta non sia stata utile. Forse dovresti modificare la tua domanda di conseguenza, perché affermazioni come: "Lo so, che in caso di cambiamento di velocità o rotta del nemico ogni calcolo deve essere ripetuto" può essere fuorviante .. se lo facessi, finiresti per avere il comportamento di "inseguimento" dello sterzo.
Bummzack,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.