I am trying using python matplotlib to draw a honeycomb animation where each hexagon is added gradually (in a spiral manner outwards, add 1 hexagon at every refresh (e.g. 200ms)). I have previously used matplotlib animation before and I know how to animate/translate a single patch by using the set_xy() of a patch, and then returning that particular patch from the animate function.
But in this particular project, I am trying to create a NEW patch/hexagon every single time from within the animate function, which gets me stuck. As you can see from my current code below, for now I am just using a primitive method to add a new 'layer' of hexagons and repeated it for 3 times. It doesn't do the animation I intended, and it adds by an entire layer of hexagons instead of just 1 hexagon.
If someone could guide me how to add more polygons/patches instead of just translating a single patch, in each animation frame I'll be happy to continue on my quest of coding it correctly.
import matplotlib.animation as animation
import matplotlib.pyplot as plt
import matplotlib.path as mpltPath
from matplotlib.patches import Polygon as poly
import numpy as np
import time
fig, ax = plt.subplots()
ax.set_aspect('equal')
plt.xlim(-5, 5)
plt.ylim(-5, 5)
class Hex():
registry = []
radius = 0.5
dist_apart = radius * np.cos(np.radians(30))*1.1
def __init__(self, center):
global ax
self.idx = len(self.__class__.registry)
self.center = center
self.vertices = self.__class__.create_vertices(self.center)
self.__class__.registry.append(self)
ax.add_patch(poly(self.vertices, fill = False))
@classmethod
def check_is_occupied(cls, center):
path = mpltPath.Path(cls.create_vertices(center))
for each_hex in cls.registry:
if path.contains_point(each_hex.center):
return True
else:
return False
@classmethod
def create_vertices(cls, center):
return np.transpose(np.array([cls.radius*(np.cos(np.radians(np.linspace(0, 300, 6))))+center[0], cls.radius*(np.sin(np.radians(np.linspace(0, 300, 6))))+center[1]]))
def fill_surround(self):
for pos in range(6):
new_center = [self.center[0] + self.__class__.dist_apart*2*np.sin(np.radians(60*(pos%6))), self.center[1] + self.__class__.dist_apart*2*np.cos(np.radians(60*(pos%6)))]
if not self.__class__.check_is_occupied(new_center):
Hex(new_center)
a = Hex([0,0])
lister = list(Hex.registry)
for each in lister:
each.fill_surround()
lister = list(Hex.registry)
for each in lister:
each.fill_surround()
lister = list(Hex.registry)
for each in lister:
each.fill_surround()
plt.show()