Setup¶
In [1]:
import math
from math import sqrt as mS
from math import pi as pi
from math import cos as cos
from math import sin as sin
import matplotlib
from matplotlib import colormaps as cm
import matplotlib.colors as mCm
from matplotlib.animation import FuncAnimation as FA
from matplotlib.patches import Circle as mpC
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from scipy.integrate import quad
import seaborn as sns
Constants & Functions¶
In [2]:
def getViridis(n):
"""
Get a viridis color sequence.
Parameters:
n - Number of colors.
Returns:
List of n hex codes as strings.
"""
return([mCm.to_hex(cm['viridis_r'].resampled(n).colors[v]) for v in range(n)])
c = getViridis(7)
#Clear axes.
def clearAx(ax):
"""
Clear axes.
Parameters:
ax - Current ax.
Returns:
ax - Updated ax.
"""
ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)
ax.spines["bottom"].set_visible(False)
ax.spines["left"].set_visible(False)
ax.set_xticks([])
ax.set_yticks([])
return(ax)
def drawWheel(ax, t, r, b) :
"""
Draw wheel at angle t.
Parameters:
ax - Current ax.
t - theta.
r - Distance light is from center of circle.
b - Draw radius boolean
Returns:
ax - Updated ax.
"""
ax.add_patch(mpC(xy = (t, 0),
radius = 1,
edgecolor = 'k',
facecolor = 'None',
lw = 1,
zorder = 1))
x = t - r*sin(t)
y = -r*cos(t)
if b :
ax.scatter(x = t,
y = 0,
s = 40,
c = c[5],
zorder = 2)
ax.plot([t, x],
[0, y],
lw = 2,
c = c[5],
zorder = 2)
ax.scatter(x = x,
y = y,
s = 40,
c = c[0],
zorder = 3)
return(ax)
def drawPath(ax, t, r) :
"""
Draw light path from 0 to t
Parameters:
ax - Current ax.
t - theta.
r - Distance light is from center of circle.
Returns:
ax - Updated ax.
"""
Xs = []
Ys = []
for i in range(int(100*t)) :
Xs.append(i/100 - r*sin(i/100))
Ys.append(-r*cos(i/100))
ax.plot(Xs, Ys, c = c[0], lw = 2)
return(ax)
In [4]:
def rollWheel(t, r) :
sns.set()
fig = plt.figure(figsize = (2*pi + 2, 3))
ax = fig.add_subplot(xlim = (-1, 2*pi + 1),
ylim = (-1.5, 1.5))
fig.subplots_adjust(left = 0, bottom = 0, right = 1, top = 1)
#Remove axes and ticks.
ax = clearAx(ax)
ax = drawWheel(ax, 0, r, True)
ax = drawWheel(ax, t/4, r, True)
ax = drawWheel(ax, t/2, r, True)
ax = drawWheel(ax, 3*t/4, r, True)
ax = drawWheel(ax, t, r, True)
ax = drawPath(ax, t, r)
fig.savefig("2026.08.21Fiddler1.png", bbox_inches = "tight")
rollWheel(6.28, 1)
Extra Credit¶
In [5]:
def intR(n) :
lengths = 0
def f(x):
r = R/n
l = mS((1-mS(r)*cos(x))**2 + (mS(r)*sin(x))**2)
return(l)
for R in range(n+1) :
L = quad(f, 0, 2*pi)[0]
lengths += L
return(lengths)
def avgLength(n) :
return(intR(n) / n)
avgLength(10000000)
C:\Users\rohan\AppData\Local\Temp\ipykernel_24628\277773165.py:12: IntegrationWarning: The occurrence of roundoff error is detected, which prevents the requested tolerance from being achieved. The error may be underestimated. L = quad(f, 0, 2*pi)[0]
Out[5]:
7.111111825237008
In [6]:
def intR2(n) :
lengths = 0
def f(x):
r = R/n
l = mS((1-r*cos(x))**2 + (r*sin(x))**2)
return(l)
for R in range(n+1) :
L = quad(f, 0, 2*pi)[0]
lengths += R*L
return(lengths)
def avgLength(n) :
return(intR2(n) / (n*(n+1) / 2))
avgLength(10000000)
C:\Users\rohan\AppData\Local\Temp\ipykernel_24628\2163193875.py:12: IntegrationWarning: The occurrence of roundoff error is detected, which prevents the requested tolerance from being achieved. The error may be underestimated. L = quad(f, 0, 2*pi)[0]
Out[6]:
7.111111199966642