Éste ejemplo no es más que una ayuda para introducir el ejemplo del salto de la rana, pues es un poco menos complejo.
El ejemplo consiste simplemente en averiguar la velocidad necesaria para lanzar un proyectil con un determinado ángulo a una determinada distancia. Aunque éste problema admite solución analítica, nosotros vamos a usar un método numérico, que es muy similar al que se emplea a menudo en problemas de contorno en equaciones diferenciales (donde la solución puede no ser tan sencilla de encontrar).
Como siempre, comenzamos creando la función principal, main()
, luego recolectamos aquellas funciones que nos hagan falta, y vamos implementando de la más sencilla a la más compleja, repitiendo el proceso para cada una de ellas.
Recuerda no comenzar a implementar una función hasta no haber acabado con la anterior.
import math
G = 9.81
def main(angle=45, rel_tol=1E-3):
# Lo primero convertimos el angulo a radianes
angle = math.radians(angle)
# El metodo se basa en saber donde acertamos la vez anterior,
# y donde acertamos esta, para estimar la velocidad para la siguiente
# Por tanto necesitamos unas conditiones iniciales para comenzar
v0, d0, v1, d1 = init(angle)
# Pedimos la distancia por teclado
d = float(input('Where is the target? '))
# Iteramos hasta encontrar una solucion
while abs(d1 - d) / d > rel_tol:
v0, d0, v1, d1 = bissection(v0, d0, v1, d1, angle, d)
# La imprimimos
print('v = {} m/s -> d = {} m'.format(v1, d1))
Por tanto tenemos dos funciones que debemos implementar:
init()
bissection
No cabe la menor duda de que init()
va a ser más sencilla.
def init(angle):
# El primer tiro puede ser sencillamente no ir a ninguna parte
v0, d0 = 0.0, 0.0
# Y el segundo tiro, pues a 1 m/s, por que no?
v1 = 1.0
d1 = shot(angle, v1)
return v0, d0, v1, d1
Por tanto, nuestra nueva función requiere de una función, shot()
que haga de solver para un determinado tiro parabólico. Puede ser discutible si es más compleja que bissection
, pero en un principio parece que será la más sencilla.
def shot(angle, v):
# Lo primero es obtener las componentes x e y de la velocidad
vx, vy = v * math.cos(angle), v * math.sin(angle)
# Con esto podemos sacar el tiempo de vuelo
t = 2 * vy / G
# Y asi el alcance
return vx * t
def bissection(x_a, f_a, x_b, f_b, angle, f):
# Reordenamos si es necesario
if f_a > f_b:
x_a, f_a, x_b, f_b = x_b, f_b, x_a, f_a
# Obtenemos una nueva aproximacion para la velocidad
if f_a < f < f_b:
x_c = 0.5 * (x_a + x_b)
else:
x_c = 2.0 * x_b
# Y el alcance correspodiente
f_c = shot(angle, x_c)
# Y comprobamos en que subintervalo esta
if f_c > f:
return x_a, f_a, x_c, f_c
return x_b, f_b, x_c, f_c
main()
Where is the target? 20 v = 14.0078125 m/s -> d = 20.001917536713176 m
En esta clase hemos visto cómo crear funciones que encapsulen tareas de nuestro programa y las hemos aplicado para respondernos ciertas preguntas sencillas.
Referencias
Las siguientes celdas contienen configuración del Notebook
Para visualizar y utlizar los enlaces a Twitter el notebook debe ejecutarse como seguro
File > Trusted Notebook
# Esta celda da el estilo al notebook
from IPython.core.display import HTML
css_file = '../styles/aeropython.css'
HTML(open(css_file, "r").read())