domingo, 9 de noviembre de 2008

Oye balas y no sabe donde...

Anoche vi la película Bangkok Dangerous, en la cual Nicolas Cage encarna el papel de un asesino. En una de las escenas el protagonista dispara con un rifle de francotirador desde el edificio de enfrente a su víctima, y como soy físico (o proyecto de ello) no pude evitar pensar con mi mente trastornada por la geometría euclídea que si me hicieran a mí lo mismo se podría saber de dónde vino el disparo gracias a que tengo contraventana.

Que qué tiene que ver la contraventana con los francotiradores? Pues muy fácil, con dos cristales que atraviese una bala (y suponiendo que no las lancen con efecto XD, como en Wanted), tenemos la recta de la trayectoria perfectamente definida. Sólo habrá que medir los datos geométricos del problema, como la distancia entre ventana y contraventana (d), etc.

Como me aburro muuuuucho, me he puesto a hacer un programa en Matlab que calcula desde dónde te dispara un francotirador a partir de los dos agujeritos que ha dejado en ventana y contraventana respectivamente. Para ello se basa en varias suposiciones, como que el disparo viene del edificio de enfrente (tiene que estar justo enfrente), que está a distancia conocida del tuyo y sobre un suelo sin desniveles. además, el edificio de enfrente tendrá que tener la misma estructura que el tuyo.

Evidentemente, esto es un problema académico más que nada, porque es muy posible que la mejor forma de determinar desde dónde te disparan (suponiendo que hayas salido vivo de ello xD) sea mirando por los dos agujeritos que haya dejado la bala y ver a dónde van a dar a parar. Pero bueno, si nos aburrimos en medir los parámetros que pide el programa (yo los he medido en un santiamen con ayuda de un metro y el Google Earth para saber la distancia al edificio de enfrente).

Con todo ello, editamos los parámtros dentro del siguiente programa:

function [piso,ventana,letraimp]=francotirador2(dx1,dy1,dx2,dy2)
%
% Este script calculará desde qué ventana le ha disparado el francotirador que tiene en el piso de enfrente.
%
disp('Este script calculará desde qué ventana le ha disparado el francotirador que tiene en el piso de enfrente.')
disp('Recuerde rellenar primero los parámetros editando el código del programa.')
disp(' ')
%
% PARÁMETROS
%
% A continuación los parámetros que deberá rellenar antes de utilizar el programa (todos los valores en las mismas unidades, originalmente yo utilizaré centímetros):
%
% DIMENSIONES DE LAS VENTANAS
% ===========================
%
%Temaño máximo horizontal de la ventana:
XV=77.0;
% Temaño máximo vertical de la ventana:
YV=136.5;
% Distancia entre ventana y contraventana:
d=14.5;
% Altura a la que está la ventana:
hvent=64.0;
% Distancia desde la pared derecha de la habitación (mirada desde el interior) al borde izquierdo de la ventana:
disvent=90.5;
%
% DATOS DEL EDIFICIO
% ==================
%
% Altura de cada piso:
H=300.0;
% Distancia al piso de enfrente:
D=4050.0;
%
% DATOS PERSONALES
% ================
%
% Tu piso
pisoini=10;
% La letra de tu piso:
tulet='B';
% Tu número de ventana empezando por la izquierda (mirando desde el exterior del edificio):
ventanaini=3;
%
% Distribución de ventanas:
% Número total de ventanas por piso:
nvent=8;
% Anchura de cada habitación correspondiente a cada una de las ventanas anteriores (de izquierda a derecha):
anch=[200.0,259.0,259.0,488.0,488.0,259.0,259.0,200.0];
% Correspondencia con la nomenclatura del piso (asociar cada ventana anterior a la "letra" de piso a la que corresponda):
letra=['A','A','B','B','C','C','D','D'];
%
% Tiene Bajo? (Si=1, No=0)
Bajo=0;
% Número de pisos (contando el bajo)
Npisos=16;
%
% -------------------------------------------------------------------------
%
% CALCULO
% =======
%
% Trayectoria
if (Bajo==1)
pisoini=pisoini+1;
end
if (ventanaini==1)
Desp=[0,(pisoini-1)*H,0];
else
Desp=[sum(anch(1:ventanaini-1)),(pisoini-1)*H,0];
end
despvent=[disvent,hvent,0];
x0=[dx1,dy1,-d]+Desp+despvent;
x1=[dx2,dy2,0]+Desp+despvent;
v=x1-x0;
%
% A distancia D
lambdaimp=D/v(3);
ximp=x1(1)+lambdaimp*v(1);
yimp=x1(2)+lambdaimp*v(2);
piso=fix(yimp/H)+1;
k=0;
ventana=0;
reco=0;
while (ventana==0 & k<=reco) ventana=k; end end fuera=0; if (ximp<0>sum(anch) | yimp<=0 | yimp>Npisos*H)
fuera=1;
disp(' ')
disp('***********************************************')
disp('EL DISPARO NO VIENE DEL EDIFICIO DE ENFRENTE!!!')
disp('***********************************************')
letraimp='?';
else
letraimp=letra(ventana);
end
%
% DIBUJO
% ======
%
X=linspace(0,sum(anch));
Y=linspace(0,Npisos*H);
close all
subplot(3,2,[3,5])
lambda=linspace(0,lambdaimp);
plot3(lambda*v(3),x1(1)+lambda*v(1),x1(2)+lambda*v(2),'r')
hold on
L=0;
plot3(0*ones(size (Y)),L*ones(size (Y)),Y)
plot3(D*ones(size (Y)),L*ones(size (Y)),Y)
% Líneas Verticales
for i=1:max(size(anch))
L=L+anch(i);
plot3(0*ones(size (Y)),L*ones(size (Y)),Y)
plot3(D*ones(size (Y)),L*ones(size (Y)),Y)
end
% Líneas Horizontales
h=0;
for j=0:Npisos
plot3(0*ones(size (X)),X,h*ones(size(X)))
plot3(D*ones(size (X)),X,h*ones(size(X)))
h=h+H;
end
if (ventanaini==1)
xv0=linspace(0,anch(1));
else
xv0=linspace(sum(anch(1:(ventanaini-1))),sum(anch(1:ventanaini)));
end
yv0=linspace((pisoini-1)*H,pisoini*H);
[XV0,YV0]=meshgrid(xv0,yv0);
mesh(0*ones(size(XV0)),XV0,YV0)
if (fuera==0)
if (ventana==1)
xvf=linspace(0,anch(1));
else
xvf=linspace(sum(anch(1:(ventana-1))),sum(anch(1:ventana)));
end
yvf=linspace((piso-1)*H,piso*H);
[XVf,YVf]=meshgrid(xvf,yvf);
mesh(D*ones(size(XVf)),XVf,YVf)
end
if (Bajo==1)
pisoa=pisoini-1;
pisob=piso-1;
else
pisoa=pisoini;
pisob=piso;
end
text(-XV,x1(1),x1(2),[num2str(pisoa),num2str(tulet)],'VerticalAlignment', 'bottom','HorizontalAlignment','right','FontWeight','bold')
text(D-XV,ximp,yimp,[num2str(pisob),num2str(letraimp)],'VerticalAlignment', 'bottom','HorizontalAlignment','right','FontWeight','bold')
title('Reconstrucción del disparo')
ylabel('Anchura de la fachada en cm')
zlabel('Altura de la fachada en cm')
%
% Otro punto de Vista:
%
subplot(3,2,2)
plot3(lambda*v(3),x1(1)+lambda*v(1),x1(2)+lambda*v(2),'r')
hold on
L=0;
plot3(0*ones(size (Y)),L*ones(size (Y)),Y)
plot3(D*ones(size (Y)),L*ones(size (Y)),Y)
% Líneas Verticales
for i=1:max(size(anch))
L=L+anch(i);
plot3(0*ones(size (Y)),L*ones(size (Y)),Y)
plot3(D*ones(size (Y)),L*ones(size (Y)),Y)
end
% Líneas Horizontales
h=0;
for j=0:Npisos
plot3(0*ones(size (X)),X,h*ones(size(X)))
plot3(D*ones(size (X)),X,h*ones(size(X)))
h=h+H;
end
mesh(0*ones(size(XV0)),XV0,YV0)
if (fuera==0)
mesh(D*ones(size(XVf)),XVf,YVf)
end
grid on
title('Vista Superior')
ylabel('Anchura de la fachada en cm')
zlabel('Altura de la fachada en cm')
view(0,90)
text(XV,x1(1),x1(2),[num2str(tulet)],'VerticalAlignment', 'bottom','HorizontalAlignment','left','FontWeight','bold')
text(D-XV,ximp,yimp,[num2str(letraimp)],'VerticalAlignment', 'bottom','HorizontalAlignment','right','FontWeight','bold')
%
% Otro punto de Vista:
%
subplot(3,2,4)
plot3(lambda*v(3),x1(1)+lambda*v(1),x1(2)+lambda*v(2),'r')
hold on
L=0;
plot3(0*ones(size (Y)),L*ones(size (Y)),Y)
plot3(D*ones(size (Y)),L*ones(size (Y)),Y)
% Líneas Verticales
for i=1:max(size(anch))
L=L+anch(i);
plot3(0*ones(size (Y)),L*ones(size (Y)),Y)
plot3(D*ones(size (Y)),L*ones(size (Y)),Y)
end
% Líneas Horizontales
h=0;
for j=0:Npisos
plot3(0*ones(size (X)),X,h*ones(size(X)))
plot3(D*ones(size (X)),X,h*ones(size(X)))
h=h+H;
end
mesh(0*ones(size(XV0)),XV0,YV0)
if (fuera==0)
mesh(D*ones(size(XVf)),XVf,YVf)
end
title('Vista Frontal')
ylabel('Anchura de la fachada en cm')
zlabel('Altura de la fachada en cm')
view(-90,0)
text(-XV,x1(1),x1(2),[num2str(pisoa),num2str(tulet)],'VerticalAlignment', 'bottom','HorizontalAlignment','right','FontWeight','bold')
text(D-XV,ximp,yimp,[num2str(pisob),num2str(letraimp)],'VerticalAlignment', 'bottom','HorizontalAlignment','right','FontWeight','bold')
%
% Otro punto de Vista:
%
subplot(3,2,6)
plot3(lambda*v(3),x1(1)+lambda*v(1),x1(2)+lambda*v(2),'r')
hold on
L=0;
plot3(0*ones(size (Y)),L*ones(size (Y)),Y)
plot3(D*ones(size (Y)),L*ones(size (Y)),Y)
% Líneas Verticales
for i=1:max(size(anch))
L=L+anch(i);
plot3(0*ones(size (Y)),L*ones(size (Y)),Y)
plot3(D*ones(size (Y)),L*ones(size (Y)),Y)
end
% Líneas Horizontales
h=0;
for j=0:Npisos
plot3(0*ones(size (X)),X,h*ones(size(X)))
plot3(D*ones(size (X)),X,h*ones(size(X)))
h=h+H;
end
mesh(0*ones(size(XV0)),XV0,YV0)
if (fuera==0)
mesh(D*ones(size(XVf)),XVf,YVf)
end
grid on
title('Vista Lateral')
ylabel('Anchura de la fachada en cm')
zlabel('Altura de la fachada en cm')
view(0,0)
text(XV,x1(1),x1(2),[num2str(pisoa),'º'],'VerticalAlignment', 'bottom','HorizontalAlignment','left','FontWeight','bold')
text(D-XV,ximp,yimp,[num2str(pisob),'º'],'VerticalAlignment', 'bottom','HorizontalAlignment','right','FontWeight','bold')
%
% Impactos en la ventana:
%
subplot(3,2,1)
xvent=linspace(0,XV);
yvent=linspace(0,YV);
plot3(-d*ones(size(yvent)),0*ones(size(yvent)),yvent)
hold on
plot3(-d*ones(size(yvent)),XV*ones(size(yvent)),yvent)
plot3(-d*ones(size(xvent)),xvent,0*ones(size(xvent)))
plot3(-d*ones(size(xvent)),xvent,YV*ones(size(xvent)))
plot3(0*ones(size(yvent)),0*ones(size(yvent)),yvent)
plot3(0*ones(size(yvent)),XV*ones(size(yvent)),yvent)
plot3(0*ones(size(xvent)),xvent,0*ones(size(xvent)))
plot3(0*ones(size(xvent)),xvent,YV*ones(size(xvent)))
plot3(-d,dx1,dy1,'g*')
plot3(0,dx2,dy2,'g*')
lambmini=linspace(0,d/v(3));
plot3(-d+lambmini*v(3),dx1+lambmini*v(1),dy1+lambmini*v(2),'r')
text(0,dx2,dy2,['(',num2str(dx2),',',num2str(dy2),')'],'VerticalAlignment', 'bottom','FontWeight','bold')
text(-d,dx1,dy1,['(',num2str(dx1),',',num2str(dy1),')'],'VerticalAlignment', 'bottom','HorizontalAlignment','right','FontWeight','bold')
grid on
title('Impactos en ventana y contraventana')
ylabel('Ancho de las ventanas en cm')
zlabel('Alto de las ventanas en cm')
%
% RESULTADOS
% ==========
%
disp('El punto de impacto es (en metros):')
disp('Horizontal:')
ximpm=ximp/100;
disp(ximpm)
disp('Vertical:')
yimpm=yimp/100;
disp(yimpm)
disp('Cordenadas correspondiente a:')
disp('Piso:')
piso=pisob;
disp(piso)
disp('Ventana')
disp(ventana)
if (fuera==0)
disp('Letra:')
disp(letraimp)
end

Guardamos el texto con nuestros datos en francotirador.m, y lo ejecutamos en Matlab, el resultado es el siguiente:

>> francotirador(77/2,136.5/2,77/2+3,136.5/2-3);
Este script calculará desde qué ventana le ha disparado el francotirador que tiene en el piso de enfrente.
Recuerde rellenar primero los parámetros editando el código del programa.

El punto de impacto es (en metros):
Horizontal:
13.2893

Vertical:
10.9132

Cordenadas correspondiente a:
Piso:
3

Ventana
5

Letra:
C


Y gráficamente, mostraría algo como lo siguiente:


(Pinchar sobre la imagen para verla a tamaño real)

Así, cuando llaméis al 112 podéis decirles desde dónde os dispararon XD.

Lo más cómodo quizá sea que os descarguéis el programa directamente de aquí:


Más que nada, porque no estoy muy seguro de que entre tanto código copiado, Blogger no lo interprete de forma que no es y desaparezcan cosas :p...

Para ejecutar el programa, teclear en MATLAB:

francotirador(dx1,dy1,dx2,dy2)

Donde (dx1,dy1) son las medidas (horizontal y vertical respectivamente) de dónde estaría el agujero de la bala en la ventana más interna (todo referido a la esquina inferior derecha, mirada desde dentro de la habitación), y (dx2,dy2) lo mismo pero del cristal más externo.

P.D.: Si alguien está intentando utilizar esto para cargase a su vecino de enfrente por sacar la basura a deshora, le diré que tal y como está hecho el programa tiene precisión sólo para apuntar a la habitación del edificio de enfrente, y no la ventana, ni mucho menos a dónde está situada la persona... vamos, que con esta precisión esto no se puede utilizar para nada malo (tampoco bueno XD).

6 comentarios:

  1. sehr gut!!

    jaja, pero este no es el problema interesante. el problema interesante es: dado un punto en uno de los cristales de mi contraventana, calcúlame los cuatro que tengo que dibujar en el otro cristal, para que cuando dispare, el tiro caiga en la ventana objetivo; sabiendo las coordenadas de dicha ventana y la mía... y más o menos en que parte de la otra ventana está la cabeza del objetivo... (si sé que se sienta a estudiar en tal sitio)

    la función de este programa en mi caso, es evidente: siendo miope solo tendría que apuntar el rifle a algo tan cercano como es mi ventana, que veo clara y nítida, para cargarme a alguien a quien no alcanzo a ver...

    aplicaciones... hay tantas aplicaciones de la geometría euclídea...

    murciélago

    ResponderEliminar
  2. Jajajajaja, cómo sabía yo que todo el mundo iba a ver este problema al revés XD.

    En el fondo pensaba que era una chorrada, que se apuntaría mejor "a ojo", sin programas de Matlab, pero en el caso que comentas tú, en el que apuntes mejor de cerca que de lejos, si podría tener cierta utilidad XD... aunque está claro que la precisión es mayor (se minimiza el error) contra más alejados estén los puntos de referencia (utilizando tu ventana y la del objetivo, en vez de dos puntos en tu ventana y contraventana).

    En cualquier caso, Astaroth's World no apoya el asesinato injustificado XD (es broma, nunca está justificado :p).

    Además, el otro día me enteré de una multa y la condena a cárcel de unos por hacer declaraciones morbosas con un aire similar en un foro... así que quede claro que ni este programa se ha hecho con fines violentos (realmente no añade ninguna "mejora" al método "tradicional"), ni la opinión del Webmaster es favorable a los actos violentos.

    Ayssss... la próxima vez haré un programa de Matlab para recoger florecillas del bosque XD, jaajjaa.

    ResponderEliminar
  3. Orale no se si algún día usare el programa pero lo guardare por si acaso xDDD.... claro hay ciertos detalles como que no tengo arma y pos ningún edificio enfrente ni de lado xDD......


    "Ayssss... la próxima vez haré un programa de Matlab para recoger florecillas del bosque XD"
    cuidado también te podrían multar por eso jajaja...

    ResponderEliminar
  4. Vale, vale, borrando programa :P

    Uff... yo que tengo clases hasta los sábados :( cambiamos horarios ^.^ jejeje....

    Bye...

    ResponderEliminar
  5. akí una k es d letras puras se keda perpleja leyendo esto,pero h de reconocer no obstante k es sin duda interesante,auk yo k tp estoy a favor del asesinato auk a veces tenga ganas d tirar a alguién montaña abajo(pero al final consigo refrenar mis impulsos y kedan en simples pensamientos...)pienso k sería más divertida una ballesta ajajaja...
    y yo k ya m las veía moradas con los problemas del instituto d
    "una piedra cae a la velocidad d .... por segundo y no se k y tal y cual y a cuanto llega al suelo?"
    ajja
    sabes?m has recordado k cuando era pekeña le disparaba con una pistola d aire comprimido desde el balcón d la casa d mis padres agazapada en el suelo arrastrándome y todo a una mujer d la limpieza k limpiaba el patio d enfrente y no m caía demasiado bien...ajjaja
    no le disparaba para darle(...)yo apuntaba a la puerta del patio dónde ella limpiaba en el interior,entonces la mujer escuchaba el ruido y salía asustada a la calle a mirar hacia los alrededores a ver kién era y yo tumbada en el suelo del balcón la miraba escondida entre las plantas y m escojonaba...ajaa...cosas d críos...
    saludos lucifer...

    ResponderEliminar
  6. "Así, cuando llaméis al 112 podéis decirles desde dónde os dispararon XD."

    Anda mira, esto también sirve para que localices desde dónde te han lanzado un rayo! ajajaajajaja

    (que quede claro que no estoy amenazando, que aún es agosto :P)

    ResponderEliminar

Querido astarothista!,

Si te ha gustado la entrada y quieres dejar constancia de ello, tienes alguna sugerencia para completarla o corregirla, quieres mostrar tu opinión respecto a algo de lo que se haya hablado en esta entrada (con respeto) o simplemente quieres dejarme un mensaje a mi o a la comunidad, no dudes en comentar ;)!

Recuerda que también estamos en Facebook y en Google+.