#! /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)