# -*- coding: utf-8 -*-
"""
Created on Fri Sep  5 17:19:22 2025

@author: AKourgli
"""

# em_propagation_3d.py
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D    # nécessaire pour 3D
import matplotlib.animation as animation

# ---------- Paramètres physiques (modifiables) ----------
c = 3e8           # m/s
f = 1e9           # Hz (1 GHz)
lam = c / f
omega = 2 * np.pi * f
k = 2 * np.pi / lam

E0 = 10.0
#H0 = E0 / 377.0   # impédance du vide   
H0=E0


# ---------- Discrétisation spatiale & temporelle ----------
num_wavelengths = 3        # afficher 2 λ le long de z
Nz = 50                    # nombre de points le long de z
z = np.linspace(0, num_wavelengths * lam, Nz)

frames_per_cycle = 30
fps = 20
dt = (1.0 / f) / frames_per_cycle
total_frames = frames_per_cycle * 3  # 3 cycles animés

# ---------- Figure 3D ----------
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')

def setup_axes():
    ax.set_xlim(0, num_wavelengths * lam)
    ax.set_ylim(-1.2 * E0, 1.2 * E0)
    ax.set_zlim(-1.2 * H0, 1.2 * H0)
    ax.set_xlabel("z (m) — propagation")
    ax.set_ylabel("E (V/m) — direction x")
    ax.set_zlabel("H (A/m) — direction y")
    ax.set_title("Propagation d'une onde EM plane : E (rouge), H (bleu), k (vert)")
    ax.grid(True)

def animate(frame):
    ax.cla()
    setup_axes()
    t = frame * dt
    Ez = E0 * np.cos(k * z - omega * t)
    Hz = H0 * np.cos(k * z - omega * t)

    X = z

    # Tracer E (rouge) comme des barres sur l'axe Y
    for i in range(len(z)):
        ax.plot([X[i], X[i]], [0, Ez[i]], [0, 0], color='r', linewidth=2)

    # Tracer H (bleu) comme des barres sur l'axe Z
    for i in range(len(z)):
        ax.plot([X[i], X[i]], [0, 0], [0, Hz[i]], color='b', linewidth=2)

    # Tracer k (vert) comme simple trait
    ax.quiver(0, 0, 0, num_wavelengths * lam * 0.8, 0, 0, color='g', linewidth=2, arrow_length_ratio=0.25)

    return []


# Lancer l'animation
ani = animation.FuncAnimation(fig, animate, frames=total_frames, interval=1000//fps, blit=False)
plt.show()
