Reflections

Reflections and focal points for different mirror geometries.

parabolic, circular, corner
import numpy as np
import matplotlib.pyplot as plt

def reflect(x, surface):
    # note: this assumes concave-up surface
    h = 1e-3
    dy = surface(x+h) - surface(x-h)
    dx = 2*h
    normal = np.array([-dy, dx])
    normal /= np.linalg.norm(normal)
    incident = np.array([0, -1])
    reflected = incident - 2 * np.dot(incident, normal) * normal
    return reflected

def plot_surface(surface_fn, xlim=(-1, 1), ax=None):
    if ax is None:
        _, ax = plt.subplots()

    # plot surface curve
    x = np.linspace(-1.09, 1.09, 100)
    y = surface_fn(x)
    ax.plot(x, y)

    # plot rays
    for x in np.linspace(xlim[0], xlim[1], 50):
        reflected = reflect(x, surface_fn)
        reflected *= -x / reflected[0]  # scale so reflected vector ends at x=0
        y = surface_fn(x)
        kwargs = dict(c='r', lw=1, alpha=0.1)
        ax.plot([x, x], [2.0, y], **kwargs)  # incident ray
        ax.plot([x, x+reflected[0]], [y, y+reflected[1]], **kwargs)  # reflected ray

    ax.axis('square')

functions = {
    # parabolic mirror -- unique focal point
    'parabolic': lambda x: x**2,
    # circular mirror -- abberation as collimation width approaches mirror diameter
    'circular': lambda x: 1 - (1.1**2 - x**2)**0.5,
    # corner retroreflector -- no focus
    'corner': lambda x: abs(x)
}
bounds = [(-0.2, 0.2), (-0.5, 0.5), (-0.9, 0.9)]
fig, axes = plt.subplots(len(bounds), len(functions), sharex=True, sharey=True, figsize=(9, 9))

for i, (label, function) in enumerate(functions.items()):
    axes[0, i].set_title(label)
    for (lo, hi), ax in zip(bounds, axes[:, i]):
        plot_surface(function, (lo, hi), ax)

fig.tight_layout()

Total running time of the script: ( 0 minutes 2.011 seconds)

Gallery generated by Sphinx-Gallery