#JCourtin 07/2016
#Last modifications 08/2016

##modules
from math import cos, sin, pi, exp
from matplotlib import pyplot as plt



#Dans tous ce PB. nous supposons que la corde est attachées à ses deux extrémités
#et qu'elle est lâchée sans vitesse initiale.

#L'étude temporelle est basée sur la fréquence d'un LA 440Hz


## 1 - Definitions de fonctions simples sur [0, L] pour les formes de cordes


#Instruments :
#-------------
def violon(x, amp=1., L=1.):
    return x*amp/L#tau -> infini
    
    
def piano(x, xCenter=0.3, width=0.3, amp=1., L=1.):#parabole 
    if (abs(x-xCenter) < width/2.):                #tau=200*T
        return amp*(1-(x-xCenter)**2)              #slt 5 harmoniques
    elif (0 <= x <= L):                            #sinon clavecin....
        return 0.
 
def guitare(x, amp=1., L=1.): #triangle qui pointe au 3/4
    xMax=3./4.*L                #tau 200 et 40 harmoniques
    if (0.<= x <= xMax):
        return amp/xMax*x
    elif (xMax< x <= L):
        return amp/(L-xMax)*(L-x)
    

#formes de base--------------------------
def triangle(x, xMax=0.02, amp=1., L=1.):
    #max atteint en xMax
    #deux portions affines


def porte(x, xc=0.0, w=1., amp=1., L=1.):
    if (abs(x-xc) < w/2.):
        return amp/w
    elif (0 <= x <= L):
        return -amp/(1-w)


def sinusoide(x, amp=1., L=1., n=1):   #a modifier
    return amp*sin(#??)



def creneaux(x, amp=1., L=1.):
    if (x<L/2.):
        return amp
    else:
        return -amp



## 2 - Analyse de Fourier de la corde.


#Objectif 1 : 

#Hyp fonction impaire sur [-L, L]  seuls coeffs -> bn
def bn(f, n, L, N=1000):
    #xk=k/N*L de 0 à L => N+1 points   et dx = L/N    car N intervalles
    ech=[#echantillons de la fonction f ]
    return #??


#renvoie la liste des modes sous la forme d'une liste de tuple
def serieFourier(f, L, N, nMax):   #tuple (n, bn)
    nStop=min(nMax, N//2)
    #A completer : on peut supprimer les modes pour lesquels 
    #|bn|<10e-10 par exemple car ils sont négligeables.


def plotSerie(coeff):
    #tracer le spectre sous la forme de barreaux verticaux
    #de hauteur |bn| avec un joli petit carré au sommet !


#Objectif 2 : 
def plotFonction(f, L, N, color='red'):
    #tracer la fonction théorique (-> f(x) N+1 points sur [0, L] inclus)
    #mais ne pas déclencher l'affichage


def syntheseFourier(f, L, N, Nmax, t=0.):
    #param phys
    c=880#m/s   440Hz sur L=1m
    T=1/440.
    coeff=serieFourier(f, L, N, Nmax)
    x = [# for k in range(N+1)]   #abscisses
    y = [0. for k in range(N+1)]      #liste de zéros

    for tup in coeff:
        y=[#?+ #?*sin(#???)*cos(#???) for k in range(N+1)]
        
    plt.plot(x, y)
    
#Objectif 3 :    On trace 11 courbe de t=0 à t=fracPeriood
def plotEvol(f, L, N, Nmax, fracPeriode):
    plt.close()
    time=[#?? for k in range(11)]
    
    #A compléter
    
    plt.show()
    


    
    
###################### MAIN ###############################################
if (__name__=='__main__'):


    L=1.0
    N=512
    Nmax=120
    
    #Choisir une des formes de corde possibles :

    
    #maCorde=lambda x:triangle(x, 0.3 , 1., L)  #--> triangle(x, xMax=0.02, amp=1., L=1.)
    maCorde=lambda x:sinusoide(x, 1., 1., 3)   #--> sinusoide(x, amp=1., L=1., n=1)
    #maCorde = lambda x:porte(x, 0.4, 0.2, 1., L) #--> porte(x, xc=0.0, w=1., amp=1., L=1.)
    #maCorde = lambda x:creneaux(x, 1., L) #--> creneaux(x, amp=1., L=1.)
    
    
    # Objectif 1 :     Calculer les bn et en déduire les coefficients de Fourier numériques.
    #-------------     En déduire le tracé du spectre des modes de Fourier.
    
    mesCoeffs = serieFourier(maCorde, L, N, Nmax)
    print(mesCoeffs)
    
    plotSerie(mesCoeffs)
    
    # Objectif 2 :     Tracer la fonction théorique de départ de la corde,
    #-------------     Et sa restitution à t=0 à l'aide de la synthèse de Fourier.
    
    """
    plt.close()
    plotFonction(maCorde, L, N, color='red')
    syntheseFourier(maCorde, L, N, Nmax, t=0.)
    plt.show()
    """
    
    
    # Objectif 3 :     Tracé l'évolution de la forme de la corde au cours du temps
    #-------------     sur une fraction de la période.
    
    #plotEvol(maCorde, L, N, Nmax, .08)




