diff --git a/lindenmayer/__main__.py b/lindenmayer/__main__.py new file mode 100644 index 0000000..70c01bc --- /dev/null +++ b/lindenmayer/__main__.py @@ -0,0 +1,17 @@ +import drawer +import turtle +turtle.tracer(0, 0) +turtleObject = turtle.Turtle() +turtleObject.hideturtle() +simulatedDraw = drawer.DrawerSimulation({"F": "F[+F]F[-F]F"}, 25.7, 1, turtle.Vec2D(0, 0), 90.0, turtleObject) +simulatedDraw.draw("F", 5) +xDistance = simulatedDraw.edges[0].max - simulatedDraw.edges[0].min +yDistance = simulatedDraw.edges[1].max - simulatedDraw.edges[1].min +xScale = turtleObject.screen.window_width() / xDistance +yScale = turtleObject.screen.window_height() / yDistance +scale = yScale if xScale > yScale else xScale +pos = turtle.Vec2D( -(simulatedDraw.edges[0].min + xDistance / 2) * scale, -(simulatedDraw.edges[1].min + yDistance / 2) * scale) +actualDrawer = drawer.Drawer({"F": "F[+F]F[-F]F"}, 25.7, scale, pos, 90.0, turtleObject) +actualDrawer.draw("F", 5) +print(turtleObject.screen._window_size()) +turtleObject.screen.exitonclick() diff --git a/lindenmayer/drawer.py b/lindenmayer/drawer.py new file mode 100644 index 0000000..8649af8 --- /dev/null +++ b/lindenmayer/drawer.py @@ -0,0 +1,62 @@ +import turtle +from dataclasses import dataclass +import typing + +@dataclass +class State: + heading: float + position: turtle.Vec2D + +class Drawer(): + def __init__(self, productionRules, angel, forwardDistance, startPosition, startRotation, turtle): + self.productionRules = productionRules + self.angel = angel + self.forwardDistance = forwardDistance + self.turtle = turtle + self.turtle.pendown() + self.turtle.setposition(startPosition) + self.turtle.setheading(startRotation) + + def storeEdges(self): + pass + + def draw(self, word, n): + turtleStates = [] + if n == 0: + self.turtle.screen.update() + return + for character in word: + match character: + case "F": + self.turtle.forward(self.forwardDistance) + self.storeEdges() + case "+": + self.turtle.left(self.angel) + case "-": + self.turtle.right(self.angel) + case "[": + turtleStates.append(State(self.turtle.heading(), self.turtle.position())) + case "]": + state = turtleStates.pop() + self.turtle.setposition(state.position) + self.turtle.setheading(state.heading) + if character in self.productionRules: + self.draw(self.productionRules[character], n - 1) + +class Edges: + def __init__(self): + self.min = 0 + self.max = 0 + +class DrawerSimulation(Drawer): + def __init__(self, productionRules, angel, forwardDistance, startPosition, startRotation, turtle): + super(DrawerSimulation, self).__init__(productionRules, angel, forwardDistance, startPosition, startRotation, turtle) + self.turtle.penup() + self.edges = [Edges(), Edges()] + + def storeEdges(self): + for i, koord in enumerate(self.turtle.position()): + if koord < self.edges[i].min: + self.edges[i].min = koord + elif koord > self.edges[i].max: + self.edges[i].max = koord