In [1]:
import numpy as np
import matplotlib.pyplot as plt
In [2]:
# Parabola, defined locus of points P such that the distance from
# a line (called the directrix) to P is equal to the distance from
# P to a fixed point F (called the focus).
lim_max, lim_min = 5, -5
a = 1
b = 0
c = 0
h = -b / (2 * a)
k = c - (b**2) / (4 * a)
generate_title = lambda a, b, c: (
'parabola: y = ' +
(f'{"x²" if a == 1 else f"{a}x²"}' if a != 0 else '') +
(f' + {"x" if b == 1 else f"{b}x"}' if b != 0 else '') +
(f' + {c}' if c != 0 else '')
).replace(' + -', ' - ')
x_point = 2
y_point = a * x_point**2 + b * x_point + c
focus_y = k + 1 / (4 * a)
directrix_y = k - 1 / (4 * a)
x = np.linspace(-10, 10, 200)
y = a * x**2 + b * x + c
plt.xlim(lim_min, lim_max)
plt.ylim(lim_min, lim_max)
plt.gca().set_aspect('equal', adjustable='box')
plt.grid(True, linestyle='--', alpha=0.6)
plt.plot(x, y, label=generate_title(a,b,c))
directrix = np.full(200, directrix_y)
plt.plot(x, directrix, label='Directrix')
plt.plot(h, focus_y, marker="o", markersize=3, color="black", label='Focus')
plt.plot(x_point, directrix_y, marker="o", markersize=3, color="black")
plt.plot([h, x_point], [focus_y, y_point], color="black")
plt.plot([x_point, x_point], [y_point, directrix_y], color="black")
radius = np.sqrt((x_point - h)**2 + (y_point - focus_y)**2)
theta = np.linspace(0, 2 * np.pi, 100)
circle_x = radius * np.cos(theta) + x_point
circle_y = radius * np.sin(theta) + y_point
plt.plot(circle_x, circle_y, color="blue", label='Circle')
slope = 2 * a * x_point + b
intercept = y_point - slope * x_point
diffx = np.linspace(-10, 10, 200)
diffy = slope * diffx + intercept
plt.plot(diffx, diffy, color="red", label='Tangent')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.title(generate_title(a,b,c))
plt.legend()
plt.show()
In [3]:
# Tangents of a Parabola
# Translated to python from xahlee's wolfram scripts
# http://xahlee.info/SpecialPlaneCurves_dir/Parabola_dir/parabola.html
def curve(t):
return t, (1/4) * t**2
def derivative(t):
return 1, (1/2) * t
t_values = np.arange(-10, 10.5, 0.5)
t_smooth = np.linspace(-10, 10, 400)
x_curve, y_curve = curve(t_smooth)
fig, ax = plt.subplots(figsize=(8, 6))
ax.plot(x_curve, y_curve, 'k', linewidth=2)
for t in t_values:
x_t, y_t = curve(t)
dx, dy = derivative(t)
tangent_x = np.linspace(x_t - 50, x_t + 50, 2)
tangent_y = y_t + (dy/dx) * (tangent_x - x_t)
color = 'red' if t < 0 else 'purple'
ax.plot(tangent_x, tangent_y, color=color, linewidth=1.5)
ax.plot(x_t, y_t, 'bo', markersize=5)
ax.set_xlim(-3, 3)
ax.set_ylim(-4.5, 3)
ax.axis('off')
ax.set_title("parametric curve with tangents")
plt.show()
In [4]:
# Optical properties of a Parabola
# Translated to python from xahlee's wolfram scripts
# http://xahlee.info/SpecialPlaneCurves_dir/Parabola_dir/parabola.html
def parabola(x):
return (1/4) * x**2
x_vals = np.linspace(-10, 10, 400)
y_vals = parabola(x_vals)
fig, ax = plt.subplots(figsize=(8, 6))
ax.plot(x_vals, y_vals, 'k', linewidth=2, label="Parabola")
ax.plot(0, 1/4, 'ro', markersize=6, label="Focus")
for x_p in np.linspace(-8, 8, 8):
y_p = parabola(x_p)
ax.plot([0, x_p], [1/4, y_p], 'b--', linewidth=1)
rx = [x_p, x_p]
ry = [y_p, y_p + 10]
ax.plot(rx, ry, 'r--', linewidth=1.5)
ax.set_xlim(-10, 10)
ax.set_ylim(-2, 10)
ax.set_xlabel("x-axis")
ax.set_ylabel("y-axis")
ax.set_title("reflection of rays from parabola's focus into parallel lines")
ax.legend()
ax.grid(True)
plt.show()
In [5]:
# My attempt to use the tangents along a parabola to form a
# temporary plane, on which I project a circle
# the projected circle is given by
# (x+f'(x)y)^2 + y^2 = r^2, where f'(x) is the tangent at a given point
# I dont have a proof that this is actually a correct projection
# still looks cool tho
import numpy as np
import matplotlib.pyplot as plt
def parabola(x):
return (1/4) * x**2
def parabola_derivative(x):
return (1/2) * x
x_tangent_points = np.linspace(-10, 10, 50)
circle_center = (0, -1)
radius = 5
theta = np.linspace(0, 2 * np.pi, 100)
y_circle = circle_center[1] + radius * np.sin(theta)
x_circle = circle_center[0] + radius * np.cos(theta)
x_transformed = x_circle + parabola_derivative(x_circle) * y_circle
radius2 = 1
theta2 = np.linspace(0, 2 * np.pi, 100)
y_circle_2 = circle_center[1] + radius2 * np.sin(theta2)
x_circle_2 = circle_center[0] + radius2 * np.cos(theta2)
x_transformed_2 = x_circle_2 + parabola_derivative(x_circle_2) * y_circle_2
fig, ax = plt.subplots(figsize=(8, 6))
x_vals = np.linspace(-10, 10, 400)
y_vals = parabola(x_vals)
ax.plot(x_vals, y_vals, 'k', linewidth=2, label="Parabola")
plt.gca().set_aspect('equal', adjustable='box')
for x_0 in x_tangent_points:
y_0 = parabola(x_0)
slope = parabola_derivative(x_0)
x_tangent = np.linspace(x_0 - 10, x_0 + 10, 10)
y_tangent = y_0 + slope * (x_tangent - x_0)
ax.plot(x_tangent, y_tangent, color="skyblue", alpha=0.4)
ax.plot(x_circle, y_circle, color="black", linestyle="--", label="Higher Original Circle", alpha=0.4)
ax.plot(x_circle_2, y_circle_2, color="black", linestyle="--", label="Lower Original Circle", alpha=0.4)
ax.plot(x_transformed, y_circle, color="purple", linestyle='-', label="Higher Distorted Circle", alpha=0.5)
ax.plot(x_transformed_2, y_circle_2, color="magenta", linestyle='-', label="Lower Distorted Circle", alpha=0.5)
ax.set_xlim(-10, 10)
ax.set_ylim(-10, 10)
ax.set_xlabel("x-axis")
ax.set_ylabel("y-axis")
ax.set_title("projection of two circles onto the tangent plane of a parabola")
ax.grid(True)
ax.legend()
plt.show()
In [6]:
# More projections, all at once
import numpy as np
import matplotlib.pyplot as plt
def parabola(x):
return (1/4) * x**2
def parabola_derivative(x):
return (1/2) * x
x_tangent_points = np.linspace(-10, 10, 50)
# THESE ARE, the edge of the axes and the directrix
circle_centers = [(0, -1/4), (0, -10), (0, 10), (-10, 0), (10, 0)]
radii = np.linspace(1, 5, 5)
theta = np.linspace(0, 2 * np.pi, 100)
fig, ax = plt.subplots(figsize=(10, 8))
x_vals = np.linspace(-10, 10, 400)
y_vals = parabola(x_vals)
ax.plot(x_vals, y_vals, 'k', linewidth=2, label="Parabola")
plt.gca().set_aspect('equal', adjustable='box')
for x_0 in x_tangent_points:
y_0 = parabola(x_0)
slope = parabola_derivative(x_0)
x_tangent = np.linspace(x_0 - 10, x_0 + 10, 10)
y_tangent = y_0 + slope * (x_tangent - x_0)
ax.plot(x_tangent, y_tangent, color="skyblue", alpha=0.4)
for center in circle_centers:
for r in radii:
y_circle = center[1] + r * np.sin(theta)
x_circle = center[0] + r * np.cos(theta)
x_transformed = x_circle + parabola_derivative(x_circle) * y_circle
ax.plot(x_circle, y_circle, color="black", linestyle="--", alpha=0.4)
ax.plot(x_transformed, y_circle, color="purple", linestyle='-', alpha=0.4)
ax.set_xlim(-10, 10)
ax.set_ylim(-10, 10)
ax.set_xlabel("x-axis")
ax.set_ylabel("y-axis")
ax.legend()
ax.set_title("projection of multiple concentric circles onto the tangent plane of a parabola")
ax.grid(True)
plt.show()