#! /usr/bin/env python
# -*- coding: utf-8 -*-

#================================================================
# satelite.py - movimiento de un cuerpo en un campo gravitatorio
#----------------------------------------------------------------
# FJA - fja@neocipres.com                           Abril de 2016
#================================================================

import sys
import argparse
from visual import *


__uso__ = '''

Ayuda:
    ===================================================================
    · satelite.py: simulación del movimiento de un satélite en el campo
    gravitatorio terrestre. Utiliza el módulo visual de VPython
    -------------------------------------------------------------------
    · Posición inicial -> un click del ratón seguido de la pulsación de
    una tecla sitúa el satélite en su posición inicial

    · I -> comienza el movimiento
    ===================================================================
'''

desc = ("%(prog)s - movimiento de un satélite en un campo gravitatorio")
parser = argparse.ArgumentParser(description=desc)

parser.add_argument('-vx', '--velx',
                    help='Componente x de la velocidad, por defecto 3072.5 m/s',
                    type=float, default=3072.5)
parser.add_argument('-vy', '--vely',
                    help='Componente y de la velocidad, por defecto 0',
                    type=float, default=0)
parser.add_argument('-vz', '--velz',
                    help='Componente z de la velocidad, por defecto 0',
                    type=float, default=0)
parser.add_argument('-q', '--deltat',
                    help='Intervalo temporal, por defecto 600 => dt = 10 s.',
                    type=int, default=600)
parser.add_argument('-o', '--traza',
                    help='Dibuja la órbita del satélite',
                    action='store_true', default=False)
parser.add_argument('-u', '--uso',
                    help='Ayuda sobre el uso del programa',
                    action='store_true', default=False)
args = parser.parse_args()

if args.uso:
    print __uso__
    sys.exit(0)

# Creamos las ventanas
ventana = display(title='Movimiento de un satélite', width=800, height=600)
ventana.autoscale = False

# Condiciones iniciales
M = 5.98e24
R = 6.380e6
G = 6.67e-11
e = R
x = 0
y = 42250500
z = 0
vecr = vector(x, y, z)
loc = (x / e, y / e, z / e)
r = vecr.mag
vx = args.velx
vy = args.vely
vz = args.velz
vecv = vector(vx, vy, vz)
v = vecv.mag
ax = 0.
ay = 0.
az = 0.
a = 0.
em = 0.
t = 0
dt = (1. / 60) * abs(args.deltat)
mover = True
nopos = True

# Creamos los objetos
tierra = sphere(pos=(0, 0, 0), radius=1, color=color.blue)
satelite = sphere(pos=(0, y / e, 0), radius=0.15, color=color.red)
orbita = curve(color=color.white)
flechav = arrow(pos=vecr / e, axis=vecv.norm(), color=color.green)
txtt = label(pos=(-9, 8, 0), box=False, text='t = ' + str(t) + ' d')
txte = label(pos=(9, 8, 0), color=color.cyan, text='E < 0')
txtr = label(pos=(-4, 8, 0), box=False, text='r = ')
txtv = label(pos=(1, 8, 0), box=False, text='v = ')
txta = label(pos=(5, 8, 0), box=False, text='g = ')

# Modificamos la posición inicial del satélite
while nopos:
    if ventana.mouse.clicked:
        m = ventana.mouse.getclick()
        loc = m.pos
        satelite.pos = loc
        flechav.pos = loc
    tecla = ventana.kb.getkey()
    if tecla == 'i' or tecla == 'I':
        x = loc[0] * e
        y = loc[1] * e
        z = loc[2] * e
        vecr = vector(x, y, z)
        r = vecr.mag
        nopos = False

# Animación
while mover:
    a = (G * M) / (r * r)
    ax = -(G * M * x) / (r * r * r)
    ay = -(G * M * y) / (r * r * r)
    az = -(G * M * z) / (r * r * r)
    vx = vx + ax * dt
    vy = vy + ay * dt
    vz = vz + az * dt
    x = x + vx * dt
    y = y + vy * dt
    z = z + vz * dt
    vecr = vector(x, y, z)
    r = vecr.mag
    vecv = vector(vx, vy, vz)
    v = vecv.mag
    em = v * v / 2 - G * M / r
    satelite.pos = vecr / e  # (x / e, y / e, z / e)
    if args.traza:
        orbita.append(vecr / e)
    t += dt
    txtt.text = 't = ' + str(round(t / (3600 * 24), 2)) + ' d'
    txtr.text = 'r = ' + str(round(r / 1000, 0)) + ' km'
    txtv.text = 'v = ' + str(round(v / 1000, 1)) + ' km/s'
    txta.text = 'g = ' + str(round(a, 2)) + ' N/kg'
    if em > 0:
        txte.color = color.red
        txte.text = 'E > 0'
    if r < R:
        break
    rate(60)