import numpy as np
import matplotlib.pyplot as plt

# Constants
electron_wavelength = 0.1  # De Broglie wavelength of electrons
slit_width = 0.1  # Width of each slit
screen_distance = 2.0  # Distance from the slits to the screen
screen_width = 2.0  # Width of the screen
screen_resolution = 800  # Number of pixels on the screen
electron_intensity = 1000  # Number of electrons emitted

# Create a grid of points on the screen
x = np.linspace(-screen_width / 2, screen_width / 2, screen_resolution)
y = np.linspace(-screen_width / 2, screen_width / 2, screen_resolution)
X, Y = np.meshgrid(x, y)

# Initialize an empty intensity matrix
intensity = np.zeros_like(X, dtype=float)

# Simulate the electron impacts on the screen
for _ in range(electron_intensity):
    # Randomly select a slit
    slit_choice = np.random.choice([-1, 1])
    
    # Randomly choose the impact point on the slit
    slit_position = np.random.uniform(-slit_width / 2, slit_width / 2) * slit_choice
    
    # Calculate the corresponding position on the screen
    x_position = screen_distance * np.tan(np.arctan2(X - slit_position, screen_distance))
    
    # Filter out positions outside the screen
    valid_positions = np.logical_and(x_position >= -screen_width / 2, x_position <= screen_width / 2)
    
    # Accumulate impacts on the screen
    intensity += valid_positions

# Create a heatmap of electron impacts
plt.figure(figsize=(8, 6))
plt.imshow(intensity, cmap='hot', extent=(-screen_width / 2, screen_width / 2, -screen_width / 2, screen_width / 2))
plt.colorbar(label='Accumulated Impacts')
plt.title('Double-Slit Experiment Heatmap (Electrons as Particles)')
plt.xlabel('X Position (meters)')
plt.ylabel('Y Position (meters)')
plt.show()


import numpy as np
import matplotlib.pyplot as plt

# Set up the experiment parameters
d = 0.1  # Width of the slits
wavelength = 0.01  # Wavelength of the waves or particles
L = 1.0  # Distance from the screen to the slits
dx = 0.01  # Spacing for the observation screen in the x-direction
dy = 0.01  # Spacing for the observation screen in the y-direction
x = np.arange(-1.0, 1.0, dx)
y = np.arange(-1.0, 1.0, dy)
X, Y = np.meshgrid(x, y)

# Calculate the intensity at each point on the screen
intensity = (
    (np.sin(np.pi * d * X / (wavelength * L))) ** 2
    * (np.sin(np.pi * d * Y / (wavelength * L))) ** 2
)

# Calculate the intensity distribution along the x-axis
intensity_x = (
    (np.sin(np.pi * d * x / (wavelength * L))) ** 2
)

# Create subplots
fig, axs = plt.subplots(1, 2, figsize=(12, 6))

# Heatmap subplot
axs[0].imshow(intensity, extent=(-1, 1, -1, 1), cmap="hot", origin="lower")
axs[0].set_title("Double-Slit Interference Heat Map")
axs[0].set_xlabel("X Position (m)")
axs[0].set_ylabel("Y Position (m)")
axs[0].grid(False)

# Distribution plot subplot
axs[1].plot(x, intensity_x, color="blue")
axs[1].set_title("Double-Slit Interference Distribution (X-axis)")
axs[1].set_xlabel("X Position (m)")
axs[1].set_ylabel("Intensity")
axs[1].grid(True)

plt.tight_layout()  # Ensure proper spacing between subplots
plt.show()


import numpy as np
import matplotlib.pyplot as plt
from ipywidgets import interact, FloatSlider

# Define the function that simulates the double-slit experiment
def double_slit_experiment(d, wavelength, L, dx, dy):
    # Create a grid of points on the screen
    x = np.arange(-1.0, 1.0, dx)
    y = np.arange(-1.0, 1.0, dy)
    X, Y = np.meshgrid(x, y)

    # Calculate the intensity at each point on the screen
    intensity = (
        (np.sin(np.pi * d * X / (wavelength * L))) ** 2
        * (np.sin(np.pi * d * Y / (wavelength * L))) ** 2
    )

    # Calculate the intensity distribution along the x-axis
    intensity_x = (
        (np.sin(np.pi * d * x / (wavelength * L))) ** 2
    )

    # Create subplots
    fig, axs = plt.subplots(1, 2, figsize=(12, 6))

    # Heatmap subplot
    axs[0].imshow(intensity, extent=(-1, 1, -1, 1), cmap="hot", origin="lower")
    axs[0].set_title("Double-Slit Interference Heat Map")
    axs[0].set_xlabel("X Position (m)")
    axs[0].set_ylabel("Y Position (m)")
    axs[0].grid(False)

    # Distribution plot subplot
    axs[1].plot(x, intensity_x, color="blue")
    axs[1].set_title("Double-Slit Interference Distribution (X-axis)")
    axs[1].set_xlabel("X Position (m)")
    axs[1].set_ylabel("Intensity")
    axs[1].grid(True)

    plt.tight_layout()  # Ensure proper spacing between subplots
    plt.show()

# Define the interactive sliders for the parameters
d_slider = FloatSlider(min=0.01, max=1.0, step=0.01, value=0.1, description='Slit Width:')
wavelength_slider = FloatSlider(min=0.001, max=0.1, step=0.001, value=0.01, description='Wavelength:')
L_slider = FloatSlider(min=0.1, max=10.0, step=0.1, value=1.0, description='Distance to Screen:')
dx_slider = FloatSlider(min=0.001, max=0.1, step=0.001, value=0.01, description='Screen Spacing (X-axis):')
dy_slider = FloatSlider(min=0.001, max=0.1, step=0.001, value=0.01, description='Screen Spacing (Y-axis):')

# Define the interactive function that updates the plot when the sliders are changed
def update_plot(d, wavelength, L, dx, dy):
    double_slit_experiment(d, wavelength, L, dx, dy)

# Create the interactive plot
interact(update_plot, d=d_slider, wavelength=wavelength_slider, L=L_slider, dx=dx_slider, dy=dy_slider)