So che questa è una domanda antica, ma penso che ci sia qualcosa che è mancato nelle risposte finora fornite. Nella domanda originale, al missile (o qualunque cosa) fu detto di accelerare verso la posizione del bersaglio. Diverse risposte hanno sottolineato che ciò era sbagliato e dovresti accelerare verso dove pensi che l'obiettivo sarà in un secondo momento. Questo è meglio ma è ancora sbagliato.
Quello che vuoi veramente fare non è accelerare verso l'obiettivo ma spostarti verso l'obiettivo. Il modo di pensare a questo è impostare la velocità desiderata puntata sul bersaglio (o una proiezione della posizione del bersaglio) e quindi capire quale accelerazione potresti applicare meglio (date le restrizioni che hai, cioè un missile probabilmente non può accelerare direttamente al contrario) per ottenere la velocità desiderata (ricordando che la velocità è un vettore).
Ecco un esempio funzionante che ho implementato stamattina, nel mio caso per un giocatore AI in un gioco di simulazione sportiva, in cui il giocatore sta cercando di inseguire il proprio avversario. Il movimento è governato da un modello standard di "kick-drift" in cui le accelerazioni vengono applicate all'inizio di un timestep per aggiornare le velocità e quindi gli oggetti si spostano a quella velocità per la durata del timestep.
Vorrei pubblicare la derivazione di questo, ma ho scoperto che non esiste alcun markup matematico supportato su questo sito. Boo! Dovrai solo fidarti che questa è la soluzione ottimale, tenendo conto del fatto che non ho restrizioni sulla direzione di accelerazione, il che non è il caso di un oggetto di tipo missilistico, quindi ciò richiederebbe alcuni vincoli extra.
Il codice è in Python, ma dovrebbe essere leggibile con qualsiasi background linguistico. Per semplicità, suppongo che ogni passaggio abbia una lunghezza di 1 ed esprimo la velocità e l'accelerazione in unità appropriate per riflettere ciò.
self.x = # current x co-ordinate
self.y = # current y co-ordinate
self.angle = # current angle of motion
self.current_speed = # current magnitude of the velocity
self.acc # Maximum acceleration player can exert on themselves
target_x = # x co-ordinate of target position or projection of it
target_y = # y co-ordinate of target position or projection of it
vx = self.current_speed * math.cos(self.angle) # current velocity x component
vy = self.current_speed * math.sin(self.angle) # current velocity y component
# Find best direction to accelerate
acc_angle = math.atan2(self.x + vx - target_x,self.y + vy - target_y)
Si noti che la funzione atan2 (a, b) calcola l'abbronzatura inversa di a / b, ma assicura che gli angoli si trovino nel quadrante corretto di un cerchio, il che richiede la conoscenza del segno sia di a che di b.
Nel mio caso, una volta ottenuta l'accelerazione, la applico per aggiornare la velocità di
vx_new = vx + self.acc * math.cos(acc_angle)
vy_new = vy + self.acc * math.sin(acc_angle)
self.current_speed = math.sqrt( vx_new**2 + vy_new**2)
self.angle = math.atan2(vy_new,vx_new)
Controllo anche la nuova velocità rispetto alla velocità massima dipendente dal giocatore e la capisco. Nel caso di un missile, un'auto o qualcosa con una velocità di rotazione massima (in gradi per tick) potresti semplicemente guardare l'angolo di movimento attuale rispetto all'ideale calcolato e se questo cambiamento è maggiore di quanto consentito, basta cambiare l'angolo di come il più possibile verso l'ideale.
Per chiunque sia interessato alla derivazione di questo, ho scritto la distanza tra il giocatore e il bersaglio dopo il timstep, in termini di posizione iniziale, velocità, velocità di accelerazione e angolo di accelerazione, quindi ho preso la derivata rispetto all'angolo di accelerazione. Impostando questo su zero si trovano i minimi della distanza target-giocatore dopo il timestep in funzione dell'angolo di accelerazione, che è esattamente ciò che vogliamo sapere. È interessante notare che, sebbene il tasso di accelerazione fosse originariamente nelle equazioni, si annulla rendendo la direzione ottimale indipendente da quanto si è effettivamente in grado di accelerare.