Source code for style

import math
from typing import Iterable


[docs]class Style: def __init__(self, style=None, **kwargs): self.index = -1
[docs] def next(self, dirx, diry): self.index += 1 return (math.atan2(diry, dirx) + math.pi) % (2 * math.pi)
[docs]class LineStyle(Style): def __init__(self, style=None, terminate=True, **kwargs): super().__init__(**kwargs) if not isinstance(style, Iterable): style = [style] self.style = style self.terminate = terminate
[docs] def get(self, index): if self.style is not None: s = self.style[index % len(self.style)] if s is not None: return s if self.terminate: self.style = None return None
[docs] def next(self, dirx, diry): super().next(dirx, diry) return self.get(self.index)
[docs]class Cross(Style): def __init__( self, vert=None, horz=None, left=None, up=None, right=None, down=None, **kwargs ): super().__init__(**kwargs) if vert is not None: if not isinstance(vert, Iterable): vert = [vert] down = vert up = vert if horz is not None: if not isinstance(horz, Iterable): self.horz = [horz] right = horz left = horz self.left = LineStyle(style=left) self.right = LineStyle(style=right) self.up = LineStyle(style=up) self.down = LineStyle(style=down)
[docs] def next(self, dirx, diry): angle = super().next(dirx, diry) # right if angle < math.pi / 4 or angle > 7 * math.pi / 4: return self.left.get(self.index) # left elif angle > 3 * math.pi / 4 and angle < 5 * math.pi / 4: return self.right.get(self.index) # up elif angle > math.pi / 4 and angle < 3 * math.pi / 4: return self.up.get(self.index) # down elif angle > 5 * math.pi / 4 and angle < 7 * math.pi / 4: return self.down.get(self.index) else: raise Exception("Angle not in range")
[docs]class Compass(Style): def __init__( self, nn=None, ne=None, ee=None, se=None, ss=None, sw=None, ww=None, nw=None, **kwargs ): super().__init__(**kwargs) self.nn = LineStyle(style=nn) self.ne = LineStyle(style=ne) self.ee = LineStyle(style=ee) self.se = LineStyle(style=se) self.ss = LineStyle(style=ss) self.sw = LineStyle(style=sw) self.ww = LineStyle(style=ww) self.nw = LineStyle(style=nw)
[docs] def next(self, dirx, diry): angle = (super().next(dirx, diry) + math.pi * 3.0 / 2.0) % (2 * math.pi) # nn if angle < math.pi / 8 or angle > 15 * math.pi / 8: return self.nn.get(self.index) # ne elif angle > math.pi / 8 and angle < 3 * math.pi / 8: return self.ne.get(self.index) # ee elif angle > 3 * math.pi / 8 and angle < 5 * math.pi / 8: return self.ee.get(self.index) # se elif angle > 5 * math.pi / 8 and angle < 7 * math.pi / 8: return self.se.get(self.index) # ss elif angle > 7 * math.pi / 8 and angle < 9 * math.pi / 8: return self.ss.get(self.index) # sw elif angle > 9 * math.pi / 8 and angle < 11 * math.pi / 8: return self.sw.get(self.index) # ww elif angle > 11 * math.pi / 8 and angle < 13 * math.pi / 8: return self.ww.get(self.index) # nw elif angle > 13 * math.pi / 8 and angle < 15 * math.pi / 8: return self.nw.get(self.index) else: raise Exception("Angle not in range")