# -*- coding: cp1252 -*-


import numpy as np
import math


from matplotlib import pyplot as plt
from matplotlib import animation


plt.rcParams['animation.ffmpeg_path'] = 'ffmpeg\\bin\\ffmpeg.exe'


fig = plt.figure()

fig.set_dpi(100)
ax = plt.axes(xlim=(-10, 10), ylim=(-10, 10))

fig.set_size_inches(20, 20)
ax.set_aspect('equal')

plt.xticks(range(-10,11))
plt.yticks(range(-10,11))
ax.grid(True)

##################



#paramÃ¨tres de l'ellipse trajectoire de la planÃ¨te

a = 6.0
b = 3.0

#interval entre deux rafraichissements (en ms)

inter = 1

#pÃ©riode de la planÃ¨te (en ms)

T = 50.0

#autres paramÃ¨tres de l'ellipse

p = (b*b)/a

c = math.sqrt(a*a-b*b)

e = c/a

#Rapport des masses étoile planète
mM = 100.0

def coord_point2(x1,x2,y1,y2):
    """calcule les coordonnÃ©es du deuxiÃ¨me point pour tracer le vecteur vitesse
    le premier point Ã©tant la position de la planÃ¨te elle mÃªme (x1,y1)"""
    xc = 15*(x2-x1)
    yc = 15*(y2-y1)

    return xc,yc
    
    



def trace_ellipse(a,b,x,y,couleur):
    """Trace une ellipse de centre (x,y) et demi grand axe a et de demi petit axe b
    de couleur couleur"""
    

    p = (b*b)/a

    c = math.sqrt(a*a-b*b)

    e= c/a

    centre = plt.Circle((x + c,y),0.1,fc='b',lw=0)
    foyer1 = plt.Circle((x,y),0.1,fc='r',lw=0)
    foyer2 = plt.Circle((x+2*c,y),0.1,fc='r',lw=0)

    ax.add_patch(centre)
    ax.add_patch(foyer1)
    ax.add_patch(foyer2)

    
    x_points = []
    y_points = []
    
    x_points = [x - c + (p/(1-e*math.cos(math.radians(i))))*math.cos(math.radians(i)) for i in range(0,365)]
    y_points = [y + (p/(1-e*math.cos(math.radians(i))))*math.sin(math.radians(i)) for i in range(0,365)]
    """

    for i in range(0,365):
        x_points.append(x + (p/(1-e*np.cos(np.radians(i))))*np.cos(np.radians(i)))
        y_points.append(y + (p/(1-e*np.cos(np.radians(i))))*np.sin(np.radians(i)))
    """    

    ellipse = ax.plot(x_points,y_points,couleur, alpha=0.7) 
    return ellipse,centre,foyer1,foyer2

## Calcul des paramÃ¨tre de l'ellipse trajectoire de l'Ã©toile
xx = (p/(1-e*math.cos(math.radians(0))))/mM # xx = a + c
yy = (p/(1-e*math.cos(math.radians(90))))/mM # yy = p
zz = (p/(1-e*math.cos(math.radians(180))))/mM # zz = a - c

print("a = " + str(xx*mM) +" b = " + str(yy*mM) +" c =  "+ str(zz*mM))

a2 = (xx +zz)/2
p2 = yy

b2 = math.sqrt(a2*p2)

c2 = math.sqrt(a2*a2 - b2*b2)
e2 = c2/a2

#Tracé de l'ellipse trajectoire de l'étoile

trace_ellipse(a2,b2,-c-c2,0,'r')

####################################################

def liste_points(x0,a,b,mM):
    """GÃ©nÃ¨re quatres listes contenant respectivement les abscisses et les ordonnÃ©es
    de la planÃ¨te et de l'étoile en tenant compte des paramÃ¨tre a et b de l'orbite
    elliptique et de la position x0 de l'Ã©toile et aussi du rapport des masses mM"""

    
    x_l= []
    y_l= []
    xe_l= []
    ye_l= []

    
    e = abs(x0)/a
    p = (b*b)/a
    sign = (x0/abs(x0))
    r = 0
    t = 0

    while(t <=360):
        r = p/(1 + sign * e * math.cos(math.radians(t)))
        
        t  =t + (2*math.pi*a*b*inter)/((r*r)*T)

        x_l.append(x0 + r * math.cos(math.radians(t)))
        y_l.append(r * math.sin(math.radians(t)))


    for i in range(0,len(x_l)):
        xe_l.append((-x_l[i] + (mM+1)*x0 )/mM)
        ye_l.append((y_l[i] )/mM)
    
    
    return x_l,y_l,xe_l,ye_l

    


x_l,y_l,xe_l,ye_l = liste_points(-c,a,b,mM)



line1, = ax.plot([0,0], [0,0], 'r')


line2, = ax.plot([0,0], [0,0], 'b')

line3, = ax.plot([0,0], [0,0], 'g')


###############################################

ellipse,centre,foyer1,foyer2 = trace_ellipse(a,b,0,0,'g')


planete = plt.Circle((a, 0),0.05,fc='r',lw=0)
    
    
ax.add_patch(planete)

   
etoile = plt.Circle((a, 0),0.05,fc='y',lw=0)
    
ax.add_patch(etoile)

d  = 'y'

##############  Animation
def init():

    
    planete = plt.Circle((a, 0),0.05,fc='r',lw=0)
    
    ax.add_patch(planete)
            
    etoile = plt.Circle((a, 0),0.05,fc='y',lw=0)
    
    ax.add_patch(etoile)    

    return planete,etoile,

def animate(i):
    x, y = planete.center
    xe, ye = etoile.center

    
    x = x_l[i%len(x_l)]
    y = y_l[i%len(y_l)]
            
    xe = xe_l[-i%len(xe_l)-1] # les coordonnées sont prises en négatif vu que l'étoile tourne dans le sens contraire
    ye = ye_l[-i%len(ye_l)-1]
    
    
    planete.center = (x, y)
    etoile.center = (xe, ye)


    line1.set_xdata([x,xe])
    line1.set_ydata([y,ye])

   

    x2,y2 = coord_point2(x,x_l[(i+1)%len(x_l)],y,y_l[(i+1)%len(y_l)])


    line2.set_xdata([x,x+2*x2])
    line2.set_ydata([y,y+2*y2])
    

    r2 = (x+c)*(x+c)+y*y

    line3.set_xdata([x,x -20*(x+c)/(math.sqrt(r2)*r2)])
    line3.set_ydata([y,y - 20*(y)/(math.sqrt(r2)*r2)])


    
    
    global d
    
    if (i<=len(x_l)):
        ax.fill([-c,x,x_l[(i+1)%len(x_l)]],[0,y,y_l[(i+1)%len(y_l)]],fc=d,lw=0.0)
    if (i %(len(x_l)//150)== 0) :
            if (d == 'y'):
                d = 'g'
            else:
                d = 'y'
                
    return planete,etoile,line1,line2,line3,


anim = animation.FuncAnimation(fig, animate, 
                               init_func=init, 
                               frames=10000, 
                               interval=inter,
                               blit=True)
    

################### Animation


mywriter = animation.FFMpegWriter()
anim.save('mymovie.mp4')




plt.show()

