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)
No description has been provided for this image

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