The Square Roots of Integers Visualized as Sharks Teeth


The Spiral of Theodorus (also known as the Snail of Pythogoras), illustrated below, is a well-known visualization of the square roots of the integers as the length of the hypotenuses of a sequence of right triangles, placed edge-to-edge.

The Spiral of Theodorus The Spiral of Theodorus [Pbroks13 at English Wikipedia: CC-SA-3.0]

An alternative visualization, highlighted in a recent tweet by user @OLonguet can be used to construct the square roots of the integers using a sequence of circles centred alternateiy on the origin, $(0, 0)$ and on $(0, 1)$. The code below generates an animation of the process, in which the intersection of neighbouring circles resembles a row of shark's teeth.

Sharks Teeth representation of the square root of consecutive integers

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

PAD = 0.05
def init():
    """Plot the sharks-tooth construction of the square roots of integers.

    The position of the (N+1)th tooth is highlighted.


    # First draw the circles on alternating centres, (0, 0) and (0, 1).
    cy = 0
    xmin = 0
    for n in range(1, nmax+1):
        r = np.sqrt(n)
        ax.add_patch(plt.Circle((0, cy), r, fill=None, ec='#aaa'))
        xmax = r
        x = np.linspace(xmin, xmax, 100)
        ax.plot(x, cy + (-1)**cy * np.sqrt(r**2 - x**2), c='k', lw=2)
        xmin = r
        cy = 1 - cy
    # Circle centres: the centre of the circle for tooth N+1 is highlighted in red.
    a_pts = ax.scatter([0, 0], [0, 1], s=32, c=['k', 'tab:red'])
    ax.text(-PAD, 0.5, '1', ha='right', va='center')

    # The radii of the wedge for tooth N+1.
    a_p1, = ax.plot([], [], c='k', lw=2)
    a_p2, = ax.plot([], [], c='tab:red', lw=2)
    # The arc of the circle for tooth N+1.
    a_arc, = ax.plot([], [], c='tab:red', lw=2)

    # Make sure circles are circular.
    ax.set_xlim(-0.2, np.sqrt(nmax) + 0.1)
    ax.set_ylim(-1., 2.)
    ax.set_yticks([0, 1])
    ax.set_xticks([np.sqrt(n) for n in range(nmax+1)])
    ax.set_xticklabels([0, 1] + [r'$\sqrt{' + str(n) + '}$' for n in range(2, nmax+1)])

    a_txt1 = ax.text(0.5, +PAD, '', ha='center', va='top', weight='bold', color='k')
    a_txt2 = ax.text(0.5, -PAD, '', ha='center', va='top', weight='bold', color='tab:red')
    return a_pts, a_p1, a_p2, a_arc, a_txt1, a_txt2

fig, ax = plt.subplots()
nmax = 10
def animate(N):
    """Advance the animation to sqrt(N+1) in frame N."""

    cyN = N % 2
    x, xp = np.sqrt(N), np.sqrt(N+1)
    # Highlight the "wedge" for this number in red.
    a_p1.set_data([x, 0, 0], [1 - cyN, 1 - cyN, cyN])
    a_p2.set_data([xp, 0, x], [cyN, cyN, 1 - cyN])
    xgrid = np.linspace(x, xp, 100)
    a_arc.set_data(xgrid, cyN + (-1)**cyN * np.sqrt(xp**2 - xgrid**2))

    # The circle centre swaps on each frame advance.
    a_pts.set_color(['k', 'tab:red'][::(cyN or -1)])

    if N:
        # Don't write sqrt(0).
        a_txt1.set_text(r'$\mathbf{\sqrt{' + str(N) + '}}$')
        a_txt1.set_x(xp / 2)
        a_txt1.set_y(1 - cyN - PAD)
    a_txt2.set_text(r'$\mathbf{\sqrt{' + str(N+1) + '}}$')
    a_txt2.set_x(xp / 2)
    a_txt2.set_y(cyN - PAD)
    return a_pts, a_p1, a_p2, a_arc, a_txt1, a_txt2

# Initialization
a_pts, a_p1, a_p2, a_arc, a_txt1, a_txt2 = init()
nframes = nmax
interval = 1000
ani = animation.FuncAnimation(fig, animate, init_func=init, frames=nframes, repeat=False,
                              interval=interval, blit=True)
# Write to GIF.
writer = animation.PillowWriter(fps=1,
                                bitrate=1800)'sharks-teeth.gif', writer=writer)
Currently unrated


Comments are pre-moderated. Please be patient and your comment will appear soon.

There are currently no comments

New Comment


required (not published)