# -*- coding: utf-8 -*-
"""
Created on Sun Sep  7 17:55:33 2025

@author: AKourgli
"""

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

# Paramètres
t = np.linspace(0, 6*np.pi, 600)
E0, B0 = 1.0, 1.0   # amplitudes

# Initialisation de la figure
fig = plt.figure(figsize=(9,6))
ax = plt.axes(projection='3d')
ax.set_xlim(0, 6*np.pi)
ax.set_ylim(-2, 2)
ax.set_zlim(-2, 2)
ax.set_xlabel("Propagation (z)")
ax.set_ylabel("Elhadi = E (vertical)")
ax.set_zlabel("Billal = B (horizontal)")
ax.set_title("Elhadi (E) et Billal (B) en stickmans reliés par la corde")

# --- fonctions pour dessiner un stickman ---
def dessiner_stickman(x, y, z, color="r"):
    """Retourne les segments d'un stickman en 3D autour de (x,y,z)."""
    taille = 0.2
    segments = []

    # Corps (ligne verticale)
    segments.append(([x, x], [y, y], [z, z+taille]))

    # Bras
    segments.append(([x, x], [y-0.15, y+0.15], [z+0.7*taille, z+0.7*taille]))

    # Jambes
    segments.append(([x, x-0.15], [y, y-0.3], [z, z-0.3]))
    segments.append(([x, x+0.15], [y, y-0.3], [z, z-0.3]))

    # Tête (cercle approximé)
    theta = np.linspace(0, 2*np.pi, 20)
    segments.append(([x+0.1*np.cos(theta)], [y+0.1*np.sin(theta)], [z+taille+0.1*np.ones(len(theta))]))

    return segments

# Conteneurs pour les artistes matplotlib
eloise_parts = []
bastien_parts = []
corde, = ax.plot([], [], [], 'k-', lw=2, label="Corde (interaction)")
traceE, = ax.plot([], [], [], 'r--', lw=1, alpha=0.6)
traceB, = ax.plot([], [], [], 'b--', lw=1, alpha=0.6)
ax.legend()

# Données pour la trace
xdataE, ydataE, zdataE = [], [], []
xdataB, ydataB, zdataB = [], [], []

# Fonction d'initialisation
def init():
    global eloise_parts, bastien_parts
    for part in eloise_parts + bastien_parts:
        part.remove()
    eloise_parts, bastien_parts = [], []
    corde.set_data([], [])
    corde.set_3d_properties([])
    traceE.set_data([], [])
    traceE.set_3d_properties([])
    traceB.set_data([], [])
    traceB.set_3d_properties([])
    return corde, traceE, traceB

# Animation
def animate(i):
    global eloise_parts, bastien_parts
    z = t[i]
    E = E0 * np.sin(z)   # déplacement vertical (Éloïse)
    B = B0 * np.sin(z)   # déplacement horizontal (Bastien)
    
    # Coordonnées
    x_e, y_e, z_e = z, E, 0
    x_b, y_b, z_b = z, 0, B

    # Nettoyer anciens stickmans
    for part in eloise_parts + bastien_parts:
        part.remove()
    eloise_parts, bastien_parts = [], []

    # Dessiner nouveaux stickmans
    for seg in dessiner_stickman(x_e, y_e, z_e, color="r"):
        part, = ax.plot(seg[0], seg[1], seg[2], color="r")
        eloise_parts.append(part)
    for seg in dessiner_stickman(x_b, y_b, z_b, color="b"):
        part, = ax.plot(seg[0], seg[1], seg[2], color="b")
        bastien_parts.append(part)

    # Corde entre Éloïse et Bastien
    corde.set_data([x_e, x_b], [y_e, y_b])
    corde.set_3d_properties([z_e, z_b])
    
    # Ajouter aux traces
    xdataE.append(x_e)
    ydataE.append(y_e)
    zdataE.append(z_e)
    xdataB.append(x_b)
    ydataB.append(y_b)
    zdataB.append(z_b)
    
    traceE.set_data(xdataE, ydataE)
    traceE.set_3d_properties(zdataE)
    traceB.set_data(xdataB, ydataB)
    traceB.set_3d_properties(zdataB)
    
    return corde, traceE, traceB, *eloise_parts, *bastien_parts

# Lancer animation
ani = animation.FuncAnimation(fig, animate, frames=len(t),
                              init_func=init, blit=False, interval=30)

plt.show()
