2011-01-20 14 views
8

Ho cercato su Google il problema ma ho trovato solo soluzioni 2D o formule che non hanno funzionato per me (ho trovato questa formula che sembra carina: http://www.ogre3d.org/forums/viewtopic.php?f=10&t=55796 ma sembra non essere corretta).sparare proiettile (traiettoria diritta) all'obiettivo in movimento in 3 dimensioni

mi hanno dato:

Vec3 cannonPos; 
Vec3 targetPos; 
Vec3 targetVelocityVec; 
float bulletSpeed; 

quello che sto cercando è il tempo t tale che

targetPos+t*targetVelocityVec 

è l'intersectionpoint dove puntare il cannone per sparare e.

Sto cercando un semplice, poco costoso per la formula t (per semplice solo che non intendo fare molte trasformazioni VectorSpace inutili e simili)

grazie!

+0

considerando il proiettile segue una traiettoria diritta rende il problema abbastanza interessante :-( – salva

risposta

15

Il vero problema è scoprire dove nello spazio il proiettile può intersecare il percorso dei bersagli. La velocità del proiettile è costante, quindi in un certo periodo di tempo percorrerà la stessa distanza indipendentemente dalla direzione in cui lo spariamo. Ciò significa che è una posizione dopo l'altra t si troverà sempre su una sfera. Ecco un esempio brutta in 2D:

Questa sfera può essere espresso matematicamente come:

(x-x_b0)^2 + (y-y_b0)^2 + (z-z_b0)^2 = (bulletSpeed * t)^2  (eq 1) 

x_b0, y_b0 e z_b0 denotano la posizione del cannone. È possibile trovare il tempo t risolvendo questa equazione per t utilizzando l'equazione fornito nella domanda:

targetPos+t*targetVelocityVec         (eq 2) 

(eq 2) è un'equazione vettoriale e può essere scomposto in tre equazioni distinte:

x = x_t0 + t * v_x 
y = y_t0 + t * v_y 
z = z_t0 + t * v_z 

Questi tre equazioni possono essere inseriti in (eq 1):

(x_t0 + t * v_x - x_b0)^2 + (y_t0 + t * v_y - y_b0)^2 + (z_t0 + t * v_z - z_b0)^2 = (bulletSpeed * t)^2 

Questa equazione contiene variabili solo noti e può essere risolto per donna. Assegnando la parte costante delle sottoespressioni quadratiche alle costanti possiamo semplificare il calcolo:

c_1 = x_t0 - x_b0 
c_2 = y_t0 - y_b0 
c_3 = z_t0 - z_b0 
(v_b = bulletSpeed) 

(t * v_x + c_1)^2 + (t * v_y + c_2)^2 + (t * v_z + c_3)^2 = (v_b * t)^2 

riorganizzare come equazione quadratica norma:

(v_x^2+v_y^2+v_z^2-v_b^2)t^2 + 2*(v_x*c_1+v_y*c_2+v_z*c_3)t + (c_1^2+c_2^2+c_3^2) = 0 

Questo è facilmente risolvibile utilizzando la formula standard. Può risultare in zero, una o due soluzioni. Soluzioni zero (senza contare soluzioni complesse) significa che non c'è modo per il proiettile di raggiungere l'obiettivo. Probabilmente una soluzione si verificherà molto raramente, quando la traiettoria target si interseca con il bordo stesso della sfera. Due soluzioni saranno lo scenario più comune. Una soluzione negativa significa che non puoi colpire il bersaglio, dal momento che avresti bisogno di sparare il proiettile nel passato. Queste sono tutte le condizioni che dovrai controllare.

Una volta risolta l'equazione, è possibile trovare la posizione di t reinserendola nello (eq 2).In pseudo codice:

# setup all needed variables 
c_1 = x_t0 - x_b0 
c_2 = y_t0 - y_b0 
c_3 = z_t0 - z_b0 
v_b = bulletSpeed 
# ... and so on 

a = v_x^2+v_y^2+v_z^2-v_b^2 
b = 2*(v_x*c_1+v_y*c_2+v_z*c_3) 
c = c_1^2+c_2^2+c_3^2 

if b^2 < 4*a*c: 
    # no real solutions 
    raise error 

p = -b/(2*a) 
q = sqrt(b^2 - 4*a*c)/(2*a) 

t1 = p-q 
t2 = p+q 

if t1 < 0 and t2 < 0: 
    # no positive solutions, all possible trajectories are in the past 
    raise error 

# we want to hit it at the earliest possible time 
if t1 > t2: t = t2 
else: t = t1 

# calculate point of collision 
x = x_t0 + t * v_x 
y = y_t0 + t * v_y 
z = z_t0 + t * v_z 
+2

Tecnicamente non "sparare il cannone * a * il passato" ma il fuoco del cannone * nella * passato per negativo ' t '. –

+0

@ Ben, buon punto Risolto: –

+0

' se t1 * t2> 0': questo può accadere se entrambe le soluzioni sono positive, quindi un errore non dovrebbe essere sollevato senza effettivamente controllare il segno (o affermando perché t1 e t2 non può essere positivo se non ci riescono.) Io uso solo "se t1 <0 e t2 <0', personalmente .. – mokus