2011-01-20 11 views
8

Ya busqué el problema en Google, pero solo encontré soluciones 2D o fórmulas que no me funcionaron (encontré esta fórmula que se ve bien: http://www.ogre3d.org/forums/viewtopic.php?f=10&t=55796 pero parece no ser correcto).disparar proyectil (trayectoria recta) al objetivo en movimiento en 3 dimensiones

me han dado:

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

lo que estoy buscando es el tiempo t tal que

targetPos+t*targetVelocityVec 

es el intersectionpoint dónde apuntar el cañón para disparar y.

Busco una fórmula simple, de bajo costo para t (por simple i simplemente no refiero a hacer muchas transformaciones VectorSpace innecesarios y similares)

gracias!

+0

teniendo en cuenta el proyectil sigue una trayectoria recta hace que el problema bastante aburridas :-( – salva

Respuesta

15

El verdadero problema consiste en descubrir en qué lugar del espacio la bala puede interceptar la trayectoria de los objetivos. La velocidad de la bala es constante, por lo que en un cierto período de tiempo recorrerá la misma distancia independientemente de la dirección en la que la disparemos. Esto significa que su posición después del tiempo t siempre estará en una esfera. Aquí está una ilustración feo en 2D:

Esta esfera se puede expresar matemáticamente como:

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

x_b0, y_b0 y z_b0 denotan la posición del cañón. Usted puede encontrar el tiempo t resolviendo esta ecuación para T utilizando la ecuación proporcionada en su pregunta:

targetPos+t*targetVelocityVec         (eq 2) 

(eq 2) es una ecuación vectorial y se puede descomponer en tres ecuaciones independientes:

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

Estos tres ecuaciones se pueden insertar en (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 

Esta ecuación contiene variables sólo se conoce y se puede resolver para t. Mediante la asignación de la parte constante de las subexpresiones cuadrática para las constantes podemos simplificar el cálculo:

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 

reorganizar como una ecuación cuadrática estándar:

(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 

Esto es fácilmente resolubles usando la fórmula estándar. Puede dar como resultado cero, una o dos soluciones. Las soluciones cero (sin contar las soluciones complejas) significan que no hay forma posible de que la bala alcance el objetivo. Una solución probablemente ocurrirá muy raramente, cuando la trayectoria del objetivo se cruza con el borde mismo de la esfera. Dos soluciones serán el escenario más común. Una solución negativa significa que no puedes alcanzar el objetivo, ya que necesitarías disparar la bala al pasado. Estas son todas las condiciones que deberá verificar.

Cuando haya resuelto la ecuación, puede encontrar la posición de t poniéndola nuevamente en (eq 2).En pseudocódigo:

# 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

Técnicamente no "disparar el cañón * * en el pasado", pero disparar el cañón * * en el pasado para el negativo ' t'. –

+0

@Ben, Buen punto. –

+0

corregido 'if t1 * t2> 0': Esto puede suceder si ambas soluciones son positivas, por lo que no se debe generar un error sin verificar el signo (o indicar por qué t1 y t2 no pueden ambos ser positivos si no pueden). Yo solo usaría 'si t1 <0 y t2 <0', personalmente. – mokus

Cuestiones relacionadas