import math
import matplotlib
from matplotlib.animation import FuncAnimation as FA
from matplotlib.patches import Polygon as mpP
import matplotlib.pyplot as plt
import numpy as np
#Rectangle corners.
c = [(-2, -1), (-2, 1), (2, 1), (2, -1)]
#Frostings
f = ['#2A788EFF', '#2A788E66',
'#440154FF', '#44015466',
'#7AD151FF', '#7AD15166']
#Polygon pieces of cake.
def polygonPiece(points, edgecolor, facecolor, lw, zo):
return(mpP(points,
edgecolor = edgecolor,
facecolor = facecolor,
lw = lw,
zorder = zo))
#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)
######For Amimation######
#x in terms of z
def X(z):
x = (-15*z**2 + 150*z) / (3*z**2 - 30*z + 300)
return(x)
#y in terms of x
def Y(x):
y = math.sqrt((-3*x + 5) * (x + 5))/3
return(y)
zs = [z/20 for z in range(101)]
xs = [X(z) for z in zs]
ys = [Y(x)/5 for x in xs]
xs = [x/5 for x in xs]
#4 quadrants
xs = xs + list(reversed(xs[0:100]))
xs = xs + [-x for x in xs[1:201]]
ys = ys + [-y for y in reversed(ys[0:100])]
ys = ys + list(reversed(ys[0:200]))
#All (x,y)
centers = [i for i in zip(xs, ys)]
zs = [z/100 for z in range(401)]
#All end of cuts along perimeter.
ends = []
for z in zs:
if z <= 2 :
ends.append([(-2, -1+z),
(0+z, 1),
(2-z, -1)])
else :
ends.append([(-2+z-2, 1),
(2, 1-z+2),
(0-z+2, -1)])
def cakeCuts(c, f, option) :
fig = plt.figure(figsize = (10, 5))
ax = fig.add_subplot(xlim = (-2.02, 2.02),
ylim = (-1.01, 1.01))
ax = clearAx(ax)
if option == 1:
center = (0, 1/3)
#Ends of 3 cuts.
es = [c[0], (0, 1), c[3]]
#3 Polygon pieces of cake.
piece1 = polygonPiece([c[0], center, c[3], c[0]], f[0], f[1], 3, 1)
piece2 = polygonPiece([c[0], c[1], es[1], center, c[0]], f[2], f[3], 3, 1)
piece3 = polygonPiece([center, es[1], c[2], c[3], center], f[4], f[5], 3, 1)
if option == 2:
center = (1/3, 0)
#Ends of 3 cuts.
es = [(-2, 0), (1, 1), (1, -1)]
#3 Polygon pieces of cake.
piece1 = polygonPiece([c[0], es[0], center, es[2], c[0]], f[0], f[1], 3, 1)
piece2 = polygonPiece([es[0], c[1], es[1], center, es[0]], f[2], f[3], 3, 1)
piece3 = polygonPiece([es[2], center, es[1], c[2], c[3], es[2]], f[4], f[5], 3, 1)
if option == 3:
center = (1/10, 1/math.sqrt(75))
#Ends of 3 cuts.
es = [(-2, -.5), (.5, 1), (1.5, -1)]
#3 Polygon pieces of cake.
piece1 = polygonPiece([c[0], es[0], center, es[2], c[0]], f[0], f[1], 3, 1)
piece2 = polygonPiece([es[0], c[0], c[1], es[1], center, es[0]], f[2], f[3], 3, 1)
piece3 = polygonPiece([es[2], center, es[1], c[2], c[3], es[2]], f[4], f[5], 3, 1)
#Origin.
plt.scatter(0, 0, c = 'k', lw = 7, zorder = 3)
#New Center.
plt.scatter(center[0], center[1], c = 'grey', lw = 7, zorder = 3)
#Horizontal & Vertical
plt.plot([-1.99, 1.99],
[center[1], center[1]],
'grey',
lw = 2,
ls = '--',
zorder = 2)
plt.plot([center[0], center[0]],
[-0.99, 0.99],
'grey',
lw = 2,
ls = '--',
zorder = 2)
text = [#Regions
("A1", (-0.6, -0.65), f[0], 36, 0),
("A2", (0.45, -0.65), f[0], 36, 0),
("B1", (center[0], 0.65), f[2], 36, 0),
("B2", (-1.65, -0.1), f[2], 36, 0),
("C1", (1.3, 0.5), f[4], 36, 0),
("C2", (1.3, -0.5), f[4], 36, 0),
#Around the perimeter.
("z", (-1.92, -0.75), 'k', 28, 90),
("5+y-z", (-1.92, (-0.5+center[1])/2), 'k', 14, 90),
("5-y", (-1.92, (1+center[1])/2), 'k', 14, 90),
("10+x", ((-2+center[0])/2, 0.92), 'k', 14, 0),
("z", ((0.5+center[0])/2-0.06, 0.92), 'k', 28, 0),
("-x", ((0.5+center[0])/2+0.03, 0.92), 'k', 14, 0),
("10-z", (1.25, 0.92), 'k', 14, 0),
("5-y", (1.92, (1+center[1])/2), 'k', 14, 270),
("5+y", (1.92, (-1+center[1])/2), 'k', 14, 270),
("z", (1.75, -.92), 'k', 28, 0),
("10-x-z", ((1.5+center[0])/2, -.92), 'k', 14, 0),
("10+x", ((-2+center[0])/2, -.92), 'k', 14, 0),
#Origin & Center.
("(0, 0)", (-0.3, -0.2), 'k', 28, 0),
("(x, y)", (center[0]+0.4, center[1]+0.15), 'gray', 28, 0),]
if option == 4:
ax = fig.add_subplot(xlim = (0, .505),
ylim = (0, 0.2525))
clearAx(ax)
#Points.
plt.scatter(0, 5/30, c = 'k', lw = 7, zorder = 3)
plt.scatter(5/30, 0, c = 'k', lw = 7, zorder = 3)
center = (1/10, 1/math.sqrt(75))
#Ends of 3 cuts.
es = [(-2, -.5), (.5, 1), (1.5, -1)]
#3 Polygon pieces of cake.
piece1 = polygonPiece([c[0], es[0], center, es[2], c[0]], None, f[1], 3, 1)
piece2 = polygonPiece([es[0], c[0], c[1], es[1], center, es[0]], None, f[3], 3, 1)
piece3 = polygonPiece([es[2], center, es[1], c[2], c[3], es[2]], None, f[5], 3, 1)
#All Centers!
xs = [x/30 for x in range(51)]
ys = np.divide([math.sqrt((-3*x+5)*(x+5))/3 for x in xs], 10)
xs = np.divide(xs, 10)
centers = polygonPiece([i for i in zip(xs, ys)] + [(0,0)] + [(xs[0], ys[0])], 'k', '#00000066', 3, 2)
#Text
text = [("(0, 5/3)", (0.05, 0.19), 'k', 28, 0),
("(5/3, 0)", (0.22, 0.01), 'k', 28, 0),]
ax.add_patch(piece1)
ax.add_patch(piece2)
ax.add_patch(piece3)
if option != 4 :
#Slices are black.
for p in es :
plt.plot([p[0], center[0]],
[p[1], center[1]],
c = 'k',
lw = 4,
zorder = 2)
if option == 3 or option == 4:
#Pow.
for t in text :
plt.annotate(text = t[0],
xy = t[1],
c = t[2],
size = t[3],
ha = "center",
va = "center",
rotation = t[4],
zorder = 2)
if option == 4 :
ax.add_patch(centers)
fig.savefig("2024.03.01" + str(option) + ".png", bbox_inches = 'tight')
cakeCuts(c, f, 1)
cakeCuts(c, f, 2)
cakeCuts(c, f, 3)
cakeCuts(c, f, 4)
matplotlib.rc_file_defaults()
fig = plt.figure(figsize = (10, 5))
ax = fig.add_subplot(xlim = (-2.02, 2.02),
ylim = (-1.01, 1.01))
ax.set_title("Threeway Equal Area and Perimeter Division of Cake", fontsize = 24)
#Remove axes and ticks.
ax = clearAx(ax)
font = {'size' : 24}
#Twelve artists:
#Piece 1, Piece 2, Piece 3,
#Slice 1, Slice 2, Slice 3,
#z1, z2, z3.
#Center Shape,
#z
#(x, y)
p1 = polygonPiece([c[0], centers[0], c[3], c[0]], f[0], f[1], 3, 1)
p2 = polygonPiece([c[0], c[1], (0,1), centers[0], c[0]], f[2], f[3], 3, 1)
p3 = polygonPiece([centers[0], (0,1), c[2], c[3], centers[0]], f[4], f[5], 3, 1)
s1 = polygonPiece([c[0], centers[0]], 'k', 'k', 4, 2)
s2 = polygonPiece([(0,1), centers[0]], 'k', 'k', 4, 2)
s3 = polygonPiece([c[3], centers[0]], 'k', 'k', 4, 2)
z1 = polygonPiece([c[0], ends[0][0]], 'gray', 'gray', 5, 3)
z2 = polygonPiece([(0, 1), ends[0][1]], 'gray', 'gray', 5, 3)
z3 = polygonPiece([c[3], ends[0][2]], 'gray', 'gray', 5, 3)
center_sh = polygonPiece([centers[0]], 'k', '#00000000', 4, 2)
z_text = ax.text(0, -1.18, '', c = 'gray', ha = 'center', **font)
xy_text = ax.text(0, 0.66, '', ha = 'center', **font)
def init():
"""Initialize seven artists."""
ax.add_patch(p1)
ax.add_patch(p2)
ax.add_patch(p3)
ax.add_patch(s1)
ax.add_patch(s2)
ax.add_patch(s3)
ax.add_patch(z1)
ax.add_patch(z2)
ax.add_patch(z3)
ax.add_patch(center_sh)
z_text.set_text('')
xy_text.set_text('')
return p1, p2, p3, s1, s2, s3, z1, z2, z3, center_sh, z_text, xy_text
def animate(i):
z = zs[i]
x = xs[i]
y = ys[i]
center = centers[i]
end = ends[i]
"""Update nine artists."""
if z <= 2 :
p1.set_xy([c[0], end[0], center, end[2], c[0]])
p2.set_xy([end[0], c[1], end[1], center, end[0]])
p3.set_xy([center, end[1], c[2], c[3], end[2], center])
z1.set_xy([c[0], end[0]])
z2.set_xy([(0, 1), end[1]])
else :
p1.set_xy([c[0], c[1], end[0], center, end[2], c[0]])
p2.set_xy([center, end[0], c[2], end[1], center])
p3.set_xy([end[2], center, end[1], c[3], end[2]])
z1.set_xy([c[0], c[1], end[0], c[1]])
z2.set_xy([(0, 1), c[2], end[1], c[2]])
z3.set_xy([c[3], end[2]])
s1.set_xy([end[0], center])
s2.set_xy([end[1], center])
s3.set_xy([end[2], center])
if i < 399:
center_sh.set_xy(centers[0:(i+1)]+ list(reversed(centers[0:(i+1)])))
else:
center_sh.set_xy(centers[0:(i+1)])
center_sh.set_facecolor('k')
z_text.set_text("z = %.2f" % (z*5))
xy_text.set_text("(x, y) = (%.2f, %.2f)" %(center[0]*5, center[1]*5))
return p1, p2, p3, s1, s2, s3, z1, z2, z3, center_sh, z_text, xy_text
#Run animation.
anim = FA(fig, animate, init_func = init, frames = 401, interval = 40, blit = True)
#Save animation.
anim.save('2024.03.01 EC.mp4');