Calificación:
  • 0 voto(s) - 0 Media
  • 1
  • 2
  • 3
  • 4
  • 5
Programa de simulación de rayo de luz
#1
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()
-----
Responder


Salto de foro:


Usuarios navegando en este tema: 1 invitado(s)