정보통신기술(ICT)

전자기학: 파동 방정식(Sine/Cosine 형태의 파동)

해머슴 2024. 10. 22. 11:47
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, TextBox
import matplotlib.animation as animation

# 초기 파동 파라미터 설정
A = 1.0        # 진폭
wavelength = 2.0  # 파장
frequency = 1.0   # 주파수
phi = 0.0      # 초기 위상

# 계산을 위한 파생 파라미터
k = 2 * np.pi / wavelength  # 파수
omega = 2 * np.pi * frequency  # 각주파수

# 공간 및 시간 범위 설정
x = np.linspace(0, 10, 1000)
time = np.linspace(0, 10, 100)

# 업데이트된 파라미터에 따라 파동 그래프를 그리는 함수
def update_plot(frame):
    global A, wavelength, frequency, phi, k, omega
    k = 2 * np.pi / wavelength  # 파수 갱신
    omega = 2 * np.pi * frequency  # 각주파수 갱신
    y = A * np.sin(k * x - omega * frame + phi)
    line.set_ydata(y)
    ax.set_title(f"Time = {frame:.2f} s")
    fig.canvas.draw_idle()

# 슬라이더 변경 시 파라미터 갱신 함수
def update_params(val):
    global A, wavelength, frequency, phi
    A = amp_slider.val
    wavelength = wavelength_slider.val
    frequency = freq_slider.val
    phi = phi_slider.val

# 텍스트 박스 제출 시 값 갱신 함수
def submit_amp(text):
    global A
    A = float(text)
    amp_slider.set_val(A)

def submit_wavelength(text):
    global wavelength
    wavelength = float(text)
    wavelength_slider.set_val(wavelength)

def submit_freq(text):
    global frequency
    frequency = float(text)
    freq_slider.set_val(frequency)

def submit_phi(text):
    global phi
    phi = float(text)
    phi_slider.set_val(phi)

# 그래프 설정
fig, ax = plt.subplots()
plt.subplots_adjust(left=0.25, bottom=0.4)
line, = ax.plot(x, A * np.sin(k * x), lw=2)
ax.set_ylim(-A, A)
ax.set_xlabel("Position (x)")
ax.set_ylabel("Amplitude (E)")

# 슬라이더 생성
ax_amp = plt.axes([0.25, 0.25, 0.65, 0.03])
ax_wavelength = plt.axes([0.25, 0.20, 0.65, 0.03])
ax_freq = plt.axes([0.25, 0.15, 0.65, 0.03])
ax_phi = plt.axes([0.25, 0.10, 0.65, 0.03])

amp_slider = Slider(ax_amp, 'Amplitude', 0.1, 5.0, valinit=A)
wavelength_slider = Slider(ax_wavelength, 'Wavelength', 0.1, 10.0, valinit=wavelength)
freq_slider = Slider(ax_freq, 'Frequency', 0.1, 5.0, valinit=frequency)
phi_slider = Slider(ax_phi, 'Phase', 0.0, 2 * np.pi, valinit=phi)

amp_slider.on_changed(update_params)
wavelength_slider.on_changed(update_params)
freq_slider.on_changed(update_params)
phi_slider.on_changed(update_params)

# 텍스트 박스 생성
axbox_amp = plt.axes([0.1, 0.25, 0.1, 0.03])
axbox_wavelength = plt.axes([0.1, 0.20, 0.1, 0.03])
axbox_freq = plt.axes([0.1, 0.15, 0.1, 0.03])
axbox_phi = plt.axes([0.1, 0.10, 0.1, 0.03])

text_box_amp = TextBox(axbox_amp, 'Amp:', initial=str(A))
text_box_wavelength = TextBox(axbox_wavelength, 'Wave:', initial=str(wavelength))
text_box_freq = TextBox(axbox_freq, 'Freq:', initial=str(frequency))
text_box_phi = TextBox(axbox_phi, 'Phase:', initial=str(phi))

text_box_amp.on_submit(submit_amp)
text_box_wavelength.on_submit(submit_wavelength)
text_box_freq.on_submit(submit_freq)
text_box_phi.on_submit(submit_phi)

# 애니메이션 설정
ani = animation.FuncAnimation(fig, update_plot, frames=time, repeat=True)

plt.show()