Animating the addition of more polygons (Python: Matplotlib)

Viewed 109

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()
0 Answers
Related