import numpy as np import holoviews as hv from holoviews import opts hv.extension('matplotlib') class DragonCurve(object): "L-system agent that follows rules to generate the Dragon Curve" initial ='FX' productions = {'X':'X+YF+', 'Y':'-FX-Y'} dragon_rules = {'F': lambda t,d,a: t.forward(d), 'B': lambda t,d,a: t.back(d), '+': lambda t,d,a: t.rotate(-a), '-': lambda t,d,a: t.rotate(a), 'X':lambda t,d,a: None, 'Y':lambda t,d,a: None } def __init__(self, x=0,y=0, iterations=1): self.heading = 0 self.distance = 5 self.angle = 90 self.x, self.y = x,y self.trace = [(self.x, self.y)] self.process(self.expand(iterations), self.distance, self.angle) def process(self, instructions, distance, angle): for i in instructions: self.dragon_rules[i](self, distance, angle) def expand(self, iterations): "Expand an initial symbol with the given production rules" expansion = self.initial for i in range(iterations): intermediate = "" for ch in expansion: intermediate = intermediate + self.productions.get(ch,ch) expansion = intermediate return expansion def forward(self, distance): self.x += np.cos(2*np.pi * self.heading/360.0) self.y += np.sin(2*np.pi * self.heading/360.0) self.trace.append((self.x,self.y)) def rotate(self, angle): self.heading += angle def back(self, distance): self.heading += 180 self.forward(distance) self.heading += 180 @property def path(self): return hv.Path([self.trace]) hmap = hv.HoloMap({i: DragonCurve(-200, 0, i).path for i in range(7,17)}, kdims='Iteration') hmap.opts( opts.Path(color='black', linewidth=1, fig_size=200, xaxis=None, yaxis=None, title='', framewise=True))