12-08-2024, 08:12 PM
Tengo este código que debe simular un rayo de luz atravesando diferentes medios, hace bien el cálculo de los ángulos de refracción pero no los gráfica correctamente, creo que puede deberse a la forma en que se cálcula la posición X y Y, agradecería demasiado su ayuda
-----
import numpy as np
import matplotlib.pyplot as plt
from tkinter import Tk, Label, Entry, Button, StringVar, messagebox
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
def snell_law(n1, n2, theta1):
"""
Aplica la ley de Snell para calcular el ángulo de refracción dado el ángulo de incidencia.
"""
theta1_rad = np.radians(theta1)
sin_theta2 = (n1 / n2) * np.sin(theta1_rad)
# Verificar si sin_theta2 está en el rango válido para arcsin
if sin_theta2 < -1 or sin_theta2 > 1:
raise ValueError("Hay reflexión total del rayo de luz")
theta2_rad = np.arcsin(sin_theta2)
return np.degrees(theta2_rad)
def calcular_trayectoria(n_indices, espesores, angulo_incidencia):
"""
Calcula la trayectoria del rayo de luz a través de los diferentes medios.
"""
angulos_refraccion = [angulo_incidencia]
puntos_x = [0]
puntos_y = [0]
x_actual = 0
y_actual = 0
angulo_actual = angulo_incidencia
for i in range(len(n_indices) - 1):
n1 = n_indices[i]
n2 = n_indices[i + 1]
espesor = espesores[i]
angulo_refraccion = snell_law(n1, n2, angulo_actual)
angulos_refraccion.append(angulo_refraccion)
distancia = espesor / np.cos(np.radians(angulo_refraccion))
x_actual += distancia * np.cos(np.radians(angulo_refraccion))
if n1 > n2:
y_actual += distancia * np.sin(np.radians(angulo_refraccion))
elif n2 > n1:
y_actual -= distancia * np.sin(np.radians(angulo_refraccion))
else:
y_actual = y_actual
puntos_x.append(x_actual)
puntos_y.append(y_actual)
# Actualizar el ángulo de incidencia para la siguiente iteración
angulo_actual = angulo_refraccion
return puntos_x, puntos_y, angulos_refraccion
def graficar_trayectoria(puntos_x, puntos_y):
"""
Grafica la trayectoria del rayo de luz.
"""
fig, ax = plt.subplots(figsize=(6, 4))
ax.plot(puntos_x, puntos_y, '-o', label='Trayectoria del rayo')
for i in range(1, len(puntos_x)):
plt.axvline(x=puntos_x[i], color='gray', linestyle='--')
ax.set_xlabel('Profundidad (cm)')
ax.set_ylabel('Distancia vertical (cm)')
ax.set_title('Trayectoria del rayo de luz en diferentes medios')
ax.axhline(0, color='black', linewidth=0.5)
ax.grid(True)
ax.legend()
return fig
def calcular_y_graficar():
"""
Obtiene los datos de entrada, calcula la trayectoria y muestra la gráfica.
"""
try:
n_indices = list(map(float, entry_n_indices.get().split(',')))
espesores = list(map(float, entry_espesores.get().split(',')))
angulo_incidencia = float(entry_angulo_incidencia.get())
if len(n_indices) != len(espesores) + 1:
messagebox.showerror("Error", "La cantidad de índices de refracción debe ser igual a la cantidad de espesores + 1.")
return
puntos_x, puntos_y, angulos_refraccion = calcular_trayectoria(n_indices, espesores, angulo_incidencia)
fig = graficar_trayectoria(puntos_x, puntos_y)
canvas = FigureCanvasTkAgg(fig, master=window)
canvas.draw()
canvas.get_tk_widget().grid(row=6, columnspan=2)
resultado.set(f"Ángulos de refracción: {angulos_refraccion}")
except Exception as e:
messagebox.showerror("Error", f"Ha ocurrido un error: {str(e)}")
# Configuración de la ventana principal
window = Tk()
window.title("Simulación de trayectoria de un rayo de luz")
# Etiquetas y entradas
Label(window, text="Índices de refracción (separados por comas):").grid(row=0, column=0)
entry_n_indices = Entry(window)
entry_n_indices.grid(row=0, column=1)
Label(window, text="Espesores de los medios (separados por comas):").grid(row=1, column=0)
entry_espesores = Entry(window)
entry_espesores.grid(row=1, column=1)
Label(window, text="Ángulo de incidencia (grados):").grid(row=2, column=0)
entry_angulo_incidencia = Entry(window)
entry_angulo_incidencia.grid(row=2, column=1)
# Botón para calcular y graficar
Button(window, text="Calcular y Graficar", command=calcular_y_graficar).grid(row=3, columnspan=2)
# Campo para mostrar resultados
resultado = StringVar()
Label(window, textvariable=resultado).grid(row=4, columnspan=2)
# Ejecución de la interfaz gráfica
window.mainloop()
-----
-----
import numpy as np
import matplotlib.pyplot as plt
from tkinter import Tk, Label, Entry, Button, StringVar, messagebox
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
def snell_law(n1, n2, theta1):
"""
Aplica la ley de Snell para calcular el ángulo de refracción dado el ángulo de incidencia.
"""
theta1_rad = np.radians(theta1)
sin_theta2 = (n1 / n2) * np.sin(theta1_rad)
# Verificar si sin_theta2 está en el rango válido para arcsin
if sin_theta2 < -1 or sin_theta2 > 1:
raise ValueError("Hay reflexión total del rayo de luz")
theta2_rad = np.arcsin(sin_theta2)
return np.degrees(theta2_rad)
def calcular_trayectoria(n_indices, espesores, angulo_incidencia):
"""
Calcula la trayectoria del rayo de luz a través de los diferentes medios.
"""
angulos_refraccion = [angulo_incidencia]
puntos_x = [0]
puntos_y = [0]
x_actual = 0
y_actual = 0
angulo_actual = angulo_incidencia
for i in range(len(n_indices) - 1):
n1 = n_indices[i]
n2 = n_indices[i + 1]
espesor = espesores[i]
angulo_refraccion = snell_law(n1, n2, angulo_actual)
angulos_refraccion.append(angulo_refraccion)
distancia = espesor / np.cos(np.radians(angulo_refraccion))
x_actual += distancia * np.cos(np.radians(angulo_refraccion))
if n1 > n2:
y_actual += distancia * np.sin(np.radians(angulo_refraccion))
elif n2 > n1:
y_actual -= distancia * np.sin(np.radians(angulo_refraccion))
else:
y_actual = y_actual
puntos_x.append(x_actual)
puntos_y.append(y_actual)
# Actualizar el ángulo de incidencia para la siguiente iteración
angulo_actual = angulo_refraccion
return puntos_x, puntos_y, angulos_refraccion
def graficar_trayectoria(puntos_x, puntos_y):
"""
Grafica la trayectoria del rayo de luz.
"""
fig, ax = plt.subplots(figsize=(6, 4))
ax.plot(puntos_x, puntos_y, '-o', label='Trayectoria del rayo')
for i in range(1, len(puntos_x)):
plt.axvline(x=puntos_x[i], color='gray', linestyle='--')
ax.set_xlabel('Profundidad (cm)')
ax.set_ylabel('Distancia vertical (cm)')
ax.set_title('Trayectoria del rayo de luz en diferentes medios')
ax.axhline(0, color='black', linewidth=0.5)
ax.grid(True)
ax.legend()
return fig
def calcular_y_graficar():
"""
Obtiene los datos de entrada, calcula la trayectoria y muestra la gráfica.
"""
try:
n_indices = list(map(float, entry_n_indices.get().split(',')))
espesores = list(map(float, entry_espesores.get().split(',')))
angulo_incidencia = float(entry_angulo_incidencia.get())
if len(n_indices) != len(espesores) + 1:
messagebox.showerror("Error", "La cantidad de índices de refracción debe ser igual a la cantidad de espesores + 1.")
return
puntos_x, puntos_y, angulos_refraccion = calcular_trayectoria(n_indices, espesores, angulo_incidencia)
fig = graficar_trayectoria(puntos_x, puntos_y)
canvas = FigureCanvasTkAgg(fig, master=window)
canvas.draw()
canvas.get_tk_widget().grid(row=6, columnspan=2)
resultado.set(f"Ángulos de refracción: {angulos_refraccion}")
except Exception as e:
messagebox.showerror("Error", f"Ha ocurrido un error: {str(e)}")
# Configuración de la ventana principal
window = Tk()
window.title("Simulación de trayectoria de un rayo de luz")
# Etiquetas y entradas
Label(window, text="Índices de refracción (separados por comas):").grid(row=0, column=0)
entry_n_indices = Entry(window)
entry_n_indices.grid(row=0, column=1)
Label(window, text="Espesores de los medios (separados por comas):").grid(row=1, column=0)
entry_espesores = Entry(window)
entry_espesores.grid(row=1, column=1)
Label(window, text="Ángulo de incidencia (grados):").grid(row=2, column=0)
entry_angulo_incidencia = Entry(window)
entry_angulo_incidencia.grid(row=2, column=1)
# Botón para calcular y graficar
Button(window, text="Calcular y Graficar", command=calcular_y_graficar).grid(row=3, columnspan=2)
# Campo para mostrar resultados
resultado = StringVar()
Label(window, textvariable=resultado).grid(row=4, columnspan=2)
# Ejecución de la interfaz gráfica
window.mainloop()
-----