Prawdziwym problemem jest ustalenie, gdzie w przestrzeni pocisk może przecinać ścieżkę celu. Prędkość pocisku jest stała, więc w pewnym czasie pokona tę samą odległość, niezależnie od kierunku, w którym ją wystrzelimy. Oznacza to, że jego pozycja po czasie t zawsze będzie leżeć na kuli. Oto brzydki ilustracja 2D:
Sfera ta może być wyrażona matematycznie jako:
(x-x_b0)^2 + (y-y_b0)^2 + (z-z_b0)^2 = (bulletSpeed * t)^2 (eq 1)
x_b0, y_b0 i z_b0 oznaczają pozycję armaty. Można znaleźć czasu t rozwiązując to równanie dla t za pomocą równania podanego w pytaniu:
targetPos+t*targetVelocityVec (eq 2)
(eq 2)
jest równanie wektorowych i mogą być rozłożone na trzy oddzielne równania:
x = x_t0 + t * v_x
y = y_t0 + t * v_y
z = z_t0 + t * v_z
Te trzy równania mogą być wstawiane do (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
równanie zawiera tylko znane zmienne i mogą być rozwiązane na ton. Przypisanie stałą część kwadratowego podwyrażeń do stałych można uproszczenia obliczeń:
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
Przegrupowanie jako standardowego równania kwadratowego:
(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
To jest łatwo rozpuszczalny przy użyciu standardowego wzoru. Może to spowodować zero, jedno lub dwa rozwiązania. Rozwiązania zerowe (nie licząc złożonych rozwiązań) oznaczają, że pocisk nie może osiągnąć celu. Jedno rozwiązanie prawdopodobnie nastąpi bardzo rzadko, gdy docelowa trajektoria przecina się z samą krawędzią kuli. Najczęstszym scenariuszem będą dwa rozwiązania. Negatywne rozwiązanie oznacza, że nie możesz trafić w cel, ponieważ musisz wystrzelić pocisk w przeszłość. Są to wszystkie warunki, które musisz sprawdzić.
Po rozwiązaniu równania można znaleźć pozycję t, ponownie wprowadzając ją do (eq 2)
.W pseudo kod:
# 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
rozważa pocisk Następuje prosta trajektoria sprawia problem dość nieciekawą :-( – salva