sábado, 7 de julio de 2012

Hancock y Balística

Esta semana, rememorando la escena de Hancock en la que le dice al gallito(bully) Michel "Llamame capullo una vez más"(Call me asshole one more time), me encontré con la siguiente pregunta: ¿Es realmente posible lanzar personas de esa manera?


Desde luego no soy la primera persona en comentar sobre ese asunto. Ya en 2009 en http://scienceblogs.com/dotphysics/2009/06/29/hancock-throws-a-boy-not-nice/ comentaban sobre el asunto (está realmente currado, me quito el sombrero Rhett). En un principio, si el crío tarda en caer 23 segundos, con simple Cinemática obtenemos que la velocidad de lanzamiento y aterrizaje sería de unos 113 m/s (406 km/h), y que alcanzaría una altitud de 649 metros (algo más que el edificio Burj Khalifa, u otros rascacielos en 2012).

Si adicionalmente utilizamos las fórmulas de fuerza de arrastre al uso, obtenemos que el "cuerpo" debería ser lanzado a unos 400 m/s (1440 km/h, Match 1.2), ascendería durante casi 8 segundos hasta una altura de casi 600m (más que cualquier rascacielos existente antes de 2010), y caería durante 15 segundos aproximándose a su velocidad terminal (unos 54 m/s). La fórmula al uso (tomada de http://en.wikipedia.org/wiki/Drag (physics)) es algo como Fdrag=.5*ρ*A*Cd*v2, donde ρ es la densidad del aire, A es el área proyectada del cuerpo, Cd es el coeficiente de arrastre del cuerpo, y v es la velocidad relativa del cuerpo. No obstante todo esto son bonitas aproximaciones: No se puede esperar que los resultados sean exactos, pero probablemente explican bien a rasgos generales el vuelo de un proyectil.

Independientemente de estas precisiones, y salvo que Michel fuera acelerado y frenado por telekinesis, tenemos un gallito muerto tres veces: en el lanzamiento (unos 5000 Gs +z), en el "choque" inicial contra la atmósfera (55 Gs -z) y en la captura (190 Gs -x).

Independientemente del artículo anterior he intentado establecer fórmulas que relacionaran la velocidad inicial, la altura alzanzada, la duración del trama ascendente y descendente. Para ello he estado unas cuantas horas cavilando y haciendo integrales con papel y lápiz y me he dado por vencido. Me he pasado al método de cálculo iterativo: Calculas los valores para t=0, y vas recalculando los valores para ti+1=ti+Δt hasta completar la simulación. Supongo que no hay ningún "deshonor" matemático en ello, ya que precisamente los ordenadores fueron utilizados en sus primeros tiempos para calcular trayectorias de misiles (claro que en esos casos hay factores como la variación de la densidad del aire o del comportamiento aerodinámico, o la fuerza de Coriolis que complican más el asunto).

Ya puestos, una vez visto que mis resultados eran congruentes con los de scienceblogs, he incorporado el concepto de ángulo de lanzamiento y de desplazamiento horizontal.Una primera aproximación ofrecía resultados parecidos a los del artículo de scienceblogs mencionado. Ya puestos he modificado para calcular la trayectoria de proyectiles lanzados a distintas alturas y con distintos ángulos. Éste sería el programa Java:
   1 package formulas.incremental;
   2 
   3 /**
   4  * Ballistic calculations for a projectile subject to gravity and Quadratic drag.
   5  * Some interesting information about drag and speed: http://en.wikipedia.org/wiki/Terminal_velocity ,
   6  * http://en.wikipedia.org/wiki/Drag_%28physics%29 , 
   7  * 
   8  * @author Javier Aranda (javier-aranda.com)
   9  * License CC BY-SA
  10  */
  11 public class Ballistic2 {
  12     // K-drag such as gravity = K / (terminal velocity)^2, as (rho * A * C_d)/(2*mass) in Rayleigh drag equation.
  13     public static final double K_DRAG_SKYDIVER = 3.365e-3; // for Terminal V.=54m/s
  14     public static final double K_DRAG_BULLET308 = 1.211e-3; // for TV=90m/s
  15     public static final double GRAVITY = 9.81; // m/s^2
  16     
  17     public static final double ELEVATION_ZENIT = Math.PI / 2;
  18     public static final double ELEVATION_45D = Math.PI / 4;
  19 
  20     public static final double DELTA_TIME = 1e-4; // How little the time slice is.
  21     
  22     // Positions in artillery shot result
  23     public static final int ASR_X=0;
  24     public static final int ASR_Z=1;
  25     public static final int ASR_T=2;
  26     public static final int ASR_IV=3; // Impact velocity
  27     public static final int ASR_IA=4; // Impact angle
  28     
  29     public static double[] artilleryShot(double v0, double elev, double z0, double kdrag) {
  30         double[] results = new double[5];
  31         boolean reachedApogee = false;
  32         boolean reachedGround = false;
  33 
  34         double tCurrent = 0;
  35         double xCurrent = 0;
  36         double zCurrent = z0;
  37         double vCurrent = v0;
  38         double vxCurrent = v0 * Math.cos(elev);
  39         double vzCurrent = v0 * Math.sin(elev);
  40         double axCurrent,azCurrent;
  41         while(!reachedGround) {
  42             // Drag and acceleration calculated over previous iteration
  43             double dragOverSpeed = kdrag * vCurrent;
  44             axCurrent = - dragOverSpeed * vxCurrent;
  45             azCurrent = - GRAVITY - dragOverSpeed * vzCurrent;
  46             
  47             tCurrent += DELTA_TIME;
  48             xCurrent += (.5 * axCurrent * DELTA_TIME + vxCurrent) * DELTA_TIME; // 1/2*a*t^2 + v*t
  49             zCurrent += (.5 * azCurrent * DELTA_TIME + vzCurrent) * DELTA_TIME;
  50             vxCurrent += axCurrent * DELTA_TIME;
  51             vzCurrent += azCurrent * DELTA_TIME;
  52             vCurrent = Math.sqrt(vxCurrent*vxCurrent + vzCurrent*vzCurrent);
  53 
  54 //          if (tCurrent % 0.5 < DELTA_TIME) {
  55 //              System.out.printf("(debug)@ t=%3.2f, ax=%3.1f, az=%3.1f, vx=%3.1f, vz=%3.1f, v=%3.1f, x=%3.1f, z=%3.1f\n",
  56 //                      tCurrent, axCurrent, azCurrent, vxCurrent, vzCurrent, vCurrent, xCurrent, zCurrent);
  57 //          }
  58 
  59             // Find out about apogee and grounding
  60             if (reachedApogee) {
  61                 if (zCurrent <= 0.0) {
  62                     reachedGround = true;
  63                     results[ASR_T] = tCurrent;
  64                     results[ASR_X] = xCurrent;
  65                     results[ASR_IV] = vCurrent;
  66                     results[ASR_IA] = Math.asin(vzCurrent / vCurrent);
  67                 }
  68             } else {
  69                 if (vzCurrent < 0.0) {
  70                     reachedApogee = true;
  71                     results[ASR_Z] = zCurrent;
  72                 }
  73             }
  74         }
  75         return results;
  76     }
  77     
  78     /**
  79      * Some test scenarios. Not worth JUnit for drafting?
  80      * @param args
  81      */
  82     public static void main(String[] args) {
  83         try {
  84             Object[][] scenarios = {
  85                     // { "Title", v0, elevation angle, z0, kdrag}
  86                     {"Hancock throws bully", 400.0, ELEVATION_ZENIT, 0.0, K_DRAG_SKYDIVER}, // http://www.youtube.com/watch?v=IzmLFEC014A 
  87                     {"Portal-diver", 54.0, ELEVATION_ZENIT, 0.0, K_DRAG_SKYDIVER}, // http://vimeo.com/43800150
  88                     {"Level bomber", 200.0, 0.0, 10000.0, K_DRAG_BULLET308 / 2},
  89                     {"Machine gun 45º", 860.0, ELEVATION_45D, 0.0, K_DRAG_BULLET308},
  90                     {"Machine gun 30º", 860.0, Math.toRadians(30), 0.0, K_DRAG_BULLET308},
  91                     {"Machine gun 15º", 860.0, Math.toRadians(15), 0.0, K_DRAG_BULLET308},
  92                     {"Machine gun  ", 860.0, Math.toRadians(5), 0.0, K_DRAG_BULLET308},
  93                     {"Machine gun  ", 860.0, Math.toRadians(2), 0.0, K_DRAG_BULLET308},
  94                     {"Machine gun  ", 860.0, Math.toRadians(1), 0.0, K_DRAG_BULLET308},
  95                     {"Machine gun close range", 860.0, Math.toRadians(0.1), 0.0, K_DRAG_BULLET308},
  96             };
  97             for (Object[] scenario : scenarios) {
  98                 double[] result = artilleryShot((Double)scenario[1], (Double)scenario[2], (Double)scenario[3], (Double)scenario[4]);
  99                 System.out.printf("Scenario %s: t=%3.2f, apogee=%3.1f, x=%3.1f, impact=%2.1f,%2.1fº\n",
 100                         scenario[0], result[ASR_T], result[ASR_Z], result[ASR_X], result[ASR_IV], result[ASR_IA] * (180/Math.PI));
 101             }
 102         } catch (Exception e) {
 103             e.printStackTrace();
 104         }
 105     }
 106 }
 107 
Los resultados de prueba son los siguientes:
Scenario Hancock throws bully: t=22,77, apogee=597,8, x=0,0, impact=53,5,-90,0º
Scenario Portal-diver: t=9,17, apogee=103,0, x=0,0, impact=38,2,-90,0º
Scenario Level bomber: t=89,81, apogee=10000,0, x=2525,6, impact=127,3,-89,9º
Scenario Machine gun 45º: t=30,25, apogee=1173,1, x=2093,0, impact=87,1,-83,0º
Scenario Machine gun 30º: t=23,43, apogee=748,3, x=2338,0, impact=82,7,-74,9º
Scenario Machine gun 15º: t=15,03, apogee=317,4, x=2250,3, impact=76,1,-52,7º
Scenario Machine gun  5º: t=7,29, apogee=72,2, x=1770,5, impact=104,0,-17,4º
Scenario Machine gun  2º: t=3,80, apogee=18,9, x=1322,0, impact=173,9,-5,4º
Scenario Machine gun  1º: t=2,23, apogee=6,4, x=992,3, impact=258,7,-2,2º
Scenario Machine gun close range: t=0,29, apogee=0,1, x=218,9, impact=659,8,-0,1º
Los resultados son más o menos congruentes con la realidad. Las bombas, aun lanzadas horizontalmente caen verticalmente y las balas (7,62 OTAN) desde larga distancia tienen poca energía cinética y asustan más que matan. Resulta llamativo (pero tiene sentido) cómo un proyectil lanzado a 45º de elevación tiene menos alcance que los lanzados a 30 o a 15, y sin embargo llega al suelo con mayor velocidad.

P.D (2012-07-27): Respecto a la tolerancia del ser humano a las aceleraciones, la tabla mostrada en scienceblog puede que no sea del todo correcta Según Wikipedia, el coronel John Stapp experimentó aceleraciones horizontales de hasta 45 G (mayores que las de la tabla, pero inferiores a las de la ficción). Se indica que a consecuencia de estos experimentos sufrió diversos traumas y desprendimiento de retina.

4 comentarios:

Alfredo dijo...

Excelente articulo tengo la siguiente duda
veo que usas como coeficiente de friccion para un 308 el valor de 0.001211, como determinaste este valor ?
Digamos que usas una bala sierra de 162 gramos y con un coeficiente de 0.462

podrias ayudarme gracias.

Javier Aranda dijo...

Hola Alfredo. Muchas gracias por la apreciación.

El rozamiento que he utilizado para proyectiles aparentemente (no me acuerdo seguro) está tomado de 90 m/s de velocidad terminal según leí en Wikipedia (munición .30-06 springfield, estudio de 1920).En realidad 0,001211 no es el coeficiente de rozamiento, si no un valor precalculado K tal que deceleración=K*v^2.

El modelado que he hecho es extremadamente sencillo (dependiendo de lo que busques probablemente no sea suficientemente riguroso). He utilizado el mismo cociente K=a/v^2 independientemente del proyectil (una bomba o un .30 de fusil de asalto/ametralladora), de la velocidad y de la densidad del aire. Tampoco recuerdo haber cotejado resultados con tablas ni nada, y el que me comentas es el primer Coeficiente de rozamiento concreto que veo para una munición.

Para el proyectil que me comentas, y suponiendo que es un 7,62mm (sección 4,56e-5 m^2), que la densidad del aire es de 1,2 kg/m^3, la fuerza de rozamiento partido v^2 sería 0,5*1,2[kg/m^3 densidad]*4,56e-5[m^2 sección]*,462[Coef_rozamiento]. Mi K sería Fuerza/v^2/masa = 1,264e-5/,165=7,66e-5. Repitiendo el modelo con este valor obtengo estos resultados, que son bastante distintos (los proyectiles alcanzan más de 10km de distancia a velocidades muy elevadas, lo cual no sé si es correcto):
Scenario Machine gun 45º: t=75,07, apogee=7118,4, x=17570,6, impact=299,7,-70,7º
Scenario Machine gun 30º: t=56,85, apogee=4129,9, x=18116,4, impact=278,8,-56,2º
Scenario Machine gun 15º: t=33,66, apogee=1435,5, x=14838,1, impact=297,1,-29,4º
Scenario Machine gun 5º: t=13,35, apogee=221,0, x=8211,7, impact=460,2,-7,5º

Adicionalmente he encontrado http://en.wikipedia.org/wiki/External_ballistics , que habla del uso de radares Doppler y de distintos modelos más realistas que el mío.

Javier Aranda dijo...

Vaya, buscando ejemplos me encuentro con que los anglosajones están utilizando pies, libras y slugs en vez de metros, newtons y kilogramos.
De los cálculos y resultados inmediatamente anteriores, en efecto mejor olvidarse (habría que convertir las medidas).

En cualquier caso las masas, secciones y formas de los proyectiles que comentamos son muy parejos. Probablemente las previsiones difieran más de la realidad por la debilidad del modelo que por la diferencia en los valores de entrada.

Alfredo dijo...

Muchas gracias!, y tienes toda la razón necesito realizar algunas conversiones del sistema ingles a l métrico.

saludos.