import math
from math import floor as mF
from math import ceil as mC
import matplotlib
from matplotlib.patches import Circle as mpC
from matplotlib.patches import Rectangle as mpS
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
#√3
r3 = math.sqrt(3)
yr3 = 1+r3/2
#𝜋
pi = math.pi
#Colors.
c = ["#4385F5", "#C9DAF8"]
#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 square(x, y):
return(mpS(xy = (x,y),
height = 1,
width = 1,
ec = c[0],
fc = c[0],
zorder = 1))
def circle(x, y):
return(mpC(xy = (x,y),
radius = 0.5,
ec = c[1],
fc = c[1],
zorder = 2))
def custDraw(x, y) :
return(plt.plot(x, y,
c = 'k',
ls = '--',
lw = 2,
zorder = 3))
def packing(option) :
#Limits
if option == 1 :
fs = (7, 7)
xlim = (0, 2)
ylim = (0, 2)
elif option == 2 :
fs = (7, 7*yr3/2)
xlim = (0, 2)
ylim = (0, 1+r3/2)
elif option == 3 :
fs = (7*5/4, 7*yr3/2)
xlim = (0, 2.5)
ylim = (0, 1+r3/2)
fig = plt.figure(figsize = fs)
ax = fig.add_subplot(xlim = xlim,
ylim = ylim)
ax = clearAx(ax)
#Bottom row. Three Squares, two circles.
ax.add_patch(square(0, 0))
ax.add_patch(square(1, 0))
ax.add_patch(square(2, 0))
ax.add_patch(circle(0.5, 0.5))
ax.add_patch(circle(1.5, 0.5))
if option == 1 :
#Bottom row. Two squares, two circles.
ax.add_patch(square(0, 1))
ax.add_patch(square(1, 1))
ax.add_patch(circle(0.5, 1.5))
ax.add_patch(circle(1.5, 1.5))
custDraw((0, 0, 1, 1, 0),
(0, 1, 1, 0, 0))
else:
#Top row. Two squares, one circle.
ax.add_patch(square(0, r3/2))
ax.add_patch(square(1, r3/2))
ax.add_patch(circle(1, yr3-1/2))
if option == 2 :
custDraw((0.5, 1, 1.5, 0.5),
(0.5, yr3-0.5, 0.5, 0.5))
custDraw((0.5, 0.5),
(0, 0.5))
plt.annotate('r', (0.425, 0.25), fontsize = 20)
custDraw((1, 1),
(0.5, yr3-0.5))
plt.annotate('r√3', (0.81, yr3/2-.1), fontsize = 20)
custDraw((1, 1),
(yr3-0.5, yr3))
plt.annotate('r', (0.925, yr3-0.25), fontsize = 20)
if option == 3 :
#Top row. Additional squares and circle.
ax.add_patch(square(2, r3/2))
ax.add_patch(circle(2, yr3-1/2))
custDraw((0.5, 1, 2, 1.5, 0.5),
(0.5, yr3-0.5, yr3-0.5, 0.5, 0.5))
custDraw((0.5, 2),
(0.5, yr3-0.5))
custDraw((1, 1.5),
(yr3-0.5, 0.5))
fig.savefig("2024.06.14Fiddler" + str(option) + ".png", bbox_inches = 'tight')
#Look at some j, k.
data = pd.DataFrame(columns = ['j',
'cj',
'k',
'ck',
'Ratio'])
for j in [h/4 for h in range(8, 801)] :
for k in [2+i*r3/4 for i in range(4, 460)]:
#Circles per row. Floor of half the length.
cj = mF(j/2)
#Even rows have same number of circles or not?
fill = False
#There is at least 1/2 left on the side.
if j - 2*cj >= 1 :
fill = True
#Circles per column.
ck = 1+mF((k-2)/r3)
#Odd Rows. cj circles per row, halfish of of circles per column.
ro = cj * mC((ck)/2)
#Even Rows.
re = (cj-1) * mF((ck)/2)
if fill :
re = cj * mF((ck)/2)
#Area.
area = j*k
#Ratio
r = (ro+re) / area
data.loc[len(data)] = [j, cj, k, ck, r]
def heatMap() :
sns.set()
fig = plt.figure(figsize = (12, 10))
ax = fig.add_subplot(xlim = (2, 200),
ylim = (2, 200))
import matplotlib.colors as mcolors
midnorm = mcolors.CenteredNorm(vcenter = 0.25)
heatmap = plt.scatter(x = data['j'],
y = data['k'],
c = data['Ratio'],
cmap = 'seismic_r',
marker = "s",
#s = 4500,
alpha = 0.8,
norm = midnorm)
#Title setup.
ax.set_title('Square or Hex Packing?', fontsize = 24)
#X-axis setup.
ax.set_xlabel('Width', fontsize = 22)
#Y-axis setup.
ax.set_ylabel('Height', fontsize = 22)
ax.tick_params(axis = 'both', which = 'major', labelsize = 18)
#Colorbar.
cb = plt.colorbar(heatmap,
format = '%.4f')
fig.savefig("2024.06.14FiddlerEC.png", bbox_inches = 'tight')
heatMap()
packing(1)
packing(2)
packing(3)