#! /usr/bin/env python # -*- coding: utf-8 -*- #========================================================== # pendulo.py - Péndulo simple con VPython #---------------------------------------------------------- # FJA - fja@neocipres.com Marzo de 2016 #========================================================== import argparse from visual import * from visual.graph import * desc = ('%(prog)s - simulación del péndulo simple') parser = argparse.ArgumentParser(description=desc) parser.add_argument('L', help='longitud (m) del péndulo', type=float) parser.add_argument('-A', '--ang', help='ángulo de inicio', type=int, default=15) parser.add_argument('-CR', '--real', help='Elimina la aproximación de ángulo pequeño, sen(a)=a', action='store_true', default=False) args = parser.parse_args() # Creamos las ventanas v = display(title='Péndulo simple', width=800, height=600) v.autoscale = False gd1 = gdisplay(x=0, y=610, width=600, height=300, title='x, v - t', xtitle='t(s)', ytitle='x, v', foreground=color.black, background=color.white) # Añadimos curvas a la ventana gd1 elongacion = gcurve(graph=gd1, color=color.magenta) velocidad = gcurve(graph=gd1, color=color.blue) # Condiciones iniciales gd = args.ang if gd > 80: gd = 80 l = round(args.L, 1) if l < 3: l = 3 if l > 15: l = 15 g = 9.81 a0 = radians(gd) t = 0 dt = 1. / 100 periodo = round(2 * pi * sqrt(l / g), 1) # Sistema de Referencia (sr) que lo creamos con un frame, y otros objetos sr = frame(x=0, y=5, z=0) masa = sphere(frame=sr, pos=(0., -l, 0.), radius=0.3, color=color.blue) hilo = cylinder(frame=sr, axis=masa.pos, radius=0.05, color=color.blue) techo = box(pos=(0, 5, 0), size=(15, 0.1, 5), color=color.red) txtl = label(pos=(-7, 7, 0), text='L = ' + str(l) + ' m') txtp = label(pos=(-4, 7, 0), text='T = ' + str(periodo) + ' s') txta = label(pos=(0, 7, 0), text='a = ' + str(gd) + u'º') txtt = label(pos=(7, 7, 0), box=False, text='t = ' + str(t) + ' s') if args.real: txtr = label(pos=(3, 7, 0), box=False, color=color.cyan, text='Real') # Preparamos las variables a = a0 da = 0 dda = 0 sr.rotate(axis=(0, 0, 1), angle=a) # Animación while 1: if v.mouse.clicked: break ec1 = -g * a / l ec2 = -g * sin(a) / l if args.real: dda = ec2 elongacion.plot(pos=(t, l * sin(a))) else: dda = ec1 elongacion.plot(pos=(t, l * a)) velocidad.plot(pos=(t, l * da)) da = da + dda * dt a = a + da * dt sr.rotate(axis=(0, 0, 1), angle=da * dt) t += dt txtt.text = 't = ' + str(round(t, 1)) + ' s' rate(100)