Setup¶

In [1]:
import math
import matplotlib
from matplotlib.patches import Circle as mpC
from matplotlib.patches import Ellipse as mpE
import matplotlib.pyplot as plt
import numpy as np

Constants and Helpers¶

In [2]:
font = {'size' : 24}

#Clear axes.
def clearAx(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 sun():
    return(mpC(xy = (0,0),
               radius = 1,
               ec = None,
               fc = "#FDB813FF"))



def getXY(m, w, i, t) :
    
    x = math.cos(i*t)
    y = math.sin(i*t)
    
    if m == 1:
        x = 0
        y = 0
    elif m == 2 :
        x = x/3
    elif m < 5 :
        x = x/2
        y = y/2
    else :
        x = w*x/2
        y = w*y/2
        
    return((x,y))



#Elliptical moon.
def ellipticalMoon(xy, w, h, t, fc, a, zo):
    
    return(mpE(xy,
               width = w,
               height = h,
               angle = t,
               ec = None,
               fc = fc,
               alpha = a,
               zorder = zo))



def eclipsePlot2() :

    fig = plt.figure(figsize = (9, 9))
    ax = fig.add_subplot(xlim = (-1.35, 1.35),
                         ylim = (-1.35, 1.35))
    ax = clearAx(ax)
    
    #Sun
    ax.add_patch(sun())
    
    w = 4/3
    h = 4/math.sqrt(3)
    xy = getXY(2, w, 0, math.pi)
    moon = ellipticalMoon(xy, w, h, 0, 'grey', 0.5, 2)
    ax.add_patch(moon)
    
    #Maff.
    f = math.sqrt(8)/3
    ax.scatter([-1/3, 0, 1, 0, 1/3, 1/3, 1/3],
               [0, 1, 0, -1, f, 0, -f],
               lw = 5,
               c = 'k',
               zorder = 4)
    ax.plot([1/3, 0, 1/3],
            [f, 1, -f],
            c = 'k',
            lw = 3,
            zorder = 4)
    
    text = [#Points
           ("(0, 1)", (-0.05, 1), 'right'),
            ("(1, 0)", (1.05, 0), 'left'),
            ("(0, -1)", (-0.05, -1), 'right'),
            ("(1-2a, 0)", (-0.38, 0), 'right'),
            ("(1-a, 0)", (0.38, 0), 'left'),
            ("(1-a, √(b²-a²))", (0.38, f), 'left'),
            ("(1-a, -√(b²-a²))", (0.38, -f), 'left')]
    for t in text :
        plt.annotate(text = t[0],
                     xy = t[1],
                     c = 'k',
                     size = 16,
                     ha = t[2],
                     va = "center",
                     zorder = 4)
    fig.savefig("2024.04.12Fiddler.png", bbox_inches = 'tight')



def eclipsePlot3() :
    
    fig = plt.figure(figsize = (9, 9))
    ax = fig.add_subplot(xlim = (-1.35, 1.35),
                         ylim = (-1.35, 1.35))
    ax = clearAx(ax)
    
    #Sun
    ax.add_patch(sun())
    
    w = 1
    h = math.sqrt(3)/2
    xy = getXY(3, w, 0, math.pi)
    moon = ellipticalMoon(xy, w, 2*h, 0, 'grey', 0.5, 2)
    ax.add_patch(moon)
    ax.plot([1/2, 0, 1/2, 1, 1/2, -1/2, -1, -1/2, 1/2, 1, 0],
            [h, 0, -h, 0, h, h, 0, -h, -h, 0, 0],
            c = 'k',
            lw = 1.5,
            zorder = 4)
    
    
    fig.savefig("2024.04.12Fiddler2.png", bbox_inches = 'tight')
In [3]:
eclipsePlot2()
In [4]:
eclipsePlot3()
In [5]:
#m elliptical moons blocking the sun.
def eclipsePlotting(m) :
    
    fig = plt.figure(figsize = (12, 8))
    ax = fig.add_subplot(xlim = (-1.35, 2.7),
                         ylim = (-1.35, 1.35))
    ax = clearAx(ax)
    
    #Sun
    ax.add_patch(sun())
    
    t = 2*math.pi/m
    
    if m == 1:
        w = 2
        h = 2
    
    elif m == 2:
        w = 4/3
        h = 4/math.sqrt(3)
    
    elif m <= 3:        
        w = 1
        h = math.sqrt(3)
            
    elif m == 4:        
        w = 1
        h = 1.553774

    else:
        xn = math.cos(t/2)
        w =  xn*4/3
        h =  4*xn*math.tan(t/2)/math.sqrt(3)

    for i in range(0, m) :
        fc = 'grey'
        a = 0.75
        zo = 2
        if i == 0:
            fc = 'k'
            a = 1
            zo = 3
        xy = getXY(m, w, i, t)
        moon = ellipticalMoon(xy, w, h, 180*i*t/math.pi, fc, a, zo)
        ax.add_patch(moon)
    
    area = math.pi * w * h / 4
    m_text = ax.text(1.57, 0.8, '%.0f Moons' % m, c = 'k', ha = 'left', **font)
    area_text = ax.text(1.57, 0.5, 'Moon Area: %.4f' % area, c = 'k', ha = 'left', **font)
    total_text = ax.text(1.57, 0.2, 'Total Moon Area: %.4f' % (area*m), c = 'k', ha = 'left', **font)
    
    if m < 10:
        strm = "00" + str(m)
    elif m < 100:
        strm = "0" + str(m)
    else:
        strm = str(m)
    fig.savefig("./anim/2024.04.12ECEclipse" + strm + ".png", bbox_inches = 'tight')
    plt.close()
In [6]:
for i in range(1, 101):
    eclipsePlotting(i)

import os
import moviepy.video.io.ImageSequenceClip
image_folder = './anim'
fps = 2

image_files = [os.path.join(image_folder,img)
               for img in os.listdir(image_folder)
               if img.endswith(".png")]
clip = moviepy.video.io.ImageSequenceClip.ImageSequenceClip(image_files, fps=fps)
clip.write_videofile('2024.04.12ECEclipse.mp4')
Moviepy - Building video 2024.04.12ECEclipse.mp4.
Moviepy - Writing video 2024.04.12ECEclipse.mp4

                                                                                                                       
Moviepy - Done !
Moviepy - video ready 2024.04.12ECEclipse.mp4

Rohan Lewis¶

2024.04.15¶