Анимация добавления дополнительных полигонов (Python: Matplotlib) - PullRequest
2 голосов
/ 01 августа 2020

Я пытаюсь использовать python matplotlib для рисования сотовой анимации, где каждый шестиугольник добавляется постепенно (по спирали наружу, добавляйте 1 шестиугольник при каждом refre sh (например, 200 мс)). Я ранее использовал анимацию matplotlib и знаю, как анимировать / переводить отдельный патч, используя set_xy() патча, а затем возвращая этот конкретный патч из функции анимации.

Но в этом конкретном проекте , Я пытаюсь создать НОВЫЙ патч / шестиугольник каждый раз из функции анимации, из-за чего я застреваю. Как вы можете видеть из моего текущего кода ниже, сейчас я просто использую примитивный метод, чтобы добавить новый «слой» шестиугольников и повторил его 3 раза. Он не выполняет ту анимацию, которую я планировал, и добавляет целый слой шестиугольников вместо одного шестиугольника. один патч в каждом кадре анимации Я буду счастлив продолжить свои поиски правильного кодирования.

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()
...