Compare commits
2 Commits
a98d1d587b
...
8f21e921db
| Author | SHA1 | Date | |
|---|---|---|---|
| 8f21e921db | |||
| ac525f8b56 |
25
lindenmayer/__main__.py
Normal file
25
lindenmayer/__main__.py
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import drawer
|
||||||
|
import turtle
|
||||||
|
import lSystems
|
||||||
|
import inputHelper
|
||||||
|
turtle.tracer(0, 0)
|
||||||
|
turtleObject = turtle.Turtle()
|
||||||
|
turtleObject.hideturtle()
|
||||||
|
for i, lSystem in enumerate(lSystems.LSystems):
|
||||||
|
print(f"{i}: {lSystem.name}")
|
||||||
|
lSystemIndex = inputHelper.inputNum(int, "Bitte ein Lindenmayer-System auswählen und die entsprechende Nummer eingeben: ", "Es gibt kein L-System mit dieser Nummer.", 0, len(lSystems.LSystems) - 1)
|
||||||
|
lSystem = lSystems.LSystems[lSystemIndex]
|
||||||
|
simulatedDraw = drawer.DrawerSimulation(lSystem.productionRules, lSystem.angel, 1, turtle.Vec2D(0, 0), 90.0, turtleObject)
|
||||||
|
simulatedDraw.draw(lSystem.startWord, 5)
|
||||||
|
maxVec = simulatedDraw.edges.maxVec()
|
||||||
|
minVec = simulatedDraw.edges.minVec()
|
||||||
|
distance = maxVec - minVec
|
||||||
|
xScale = turtleObject.screen.window_width() / distance[0]
|
||||||
|
yScale = turtleObject.screen.window_height() / distance[1]
|
||||||
|
scale = yScale if xScale > yScale else xScale
|
||||||
|
pos = (-minVec - distance * (1/2)) * scale
|
||||||
|
print(pos)
|
||||||
|
print(distance)
|
||||||
|
actualDrawer = drawer.Drawer(lSystem.productionRules, lSystem.angel, scale, pos, 90.0, turtleObject)
|
||||||
|
actualDrawer.draw(lSystem.startWord, 5)
|
||||||
|
turtleObject.screen.exitonclick()
|
||||||
67
lindenmayer/drawer.py
Normal file
67
lindenmayer/drawer.py
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
import turtle
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
@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, 0]
|
||||||
|
self.max = [0, 0]
|
||||||
|
|
||||||
|
def minVec(self):
|
||||||
|
return turtle.Vec2D(self.min[0], self.min[1])
|
||||||
|
|
||||||
|
def maxVec(self):
|
||||||
|
return turtle.Vec2D(self.max[0], self.max[1])
|
||||||
|
|
||||||
|
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()
|
||||||
|
|
||||||
|
def storeEdges(self):
|
||||||
|
for i, koord in enumerate(self.turtle.position()):
|
||||||
|
if koord < self.edges.min[i]:
|
||||||
|
self.edges.min[i] = koord
|
||||||
|
elif koord > self.edges.max[i]:
|
||||||
|
self.edges.max[i] = koord
|
||||||
13
lindenmayer/input.py
Normal file
13
lindenmayer/input.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
def inputInt(description, indexErrorMsg):
|
||||||
|
lSystemIndex: int
|
||||||
|
while inputError:
|
||||||
|
try:
|
||||||
|
lSystemIndex = int(input(description))
|
||||||
|
except ValueError:
|
||||||
|
print("Fehler: keine gültige Zahl")
|
||||||
|
continue
|
||||||
|
inputError = lSystemIndex < 0 or lSystemIndex >= len(lSystems.LSystems)
|
||||||
|
if inputError:
|
||||||
|
print(indexErrorMsg)
|
||||||
|
|
||||||
|
return lSystemIndex
|
||||||
17
lindenmayer/inputHelper.py
Normal file
17
lindenmayer/inputHelper.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
def inputNum(inputType, description, rangeErrorMsg, minRange, maxRange, defaultValue = None):
|
||||||
|
n: int
|
||||||
|
inputError = True
|
||||||
|
while inputError:
|
||||||
|
inputValue = input(description)
|
||||||
|
try:
|
||||||
|
n = inputType(inputValue)
|
||||||
|
except ValueError:
|
||||||
|
if inputValue == "" and defaultValue != None:
|
||||||
|
return defaultValue
|
||||||
|
print("Fehler: keine gültige Zahl")
|
||||||
|
continue
|
||||||
|
inputError = n < minRange or n > maxRange
|
||||||
|
if inputError:
|
||||||
|
print(rangeErrorMsg)
|
||||||
|
|
||||||
|
return n
|
||||||
18
lindenmayer/lSystems.py
Normal file
18
lindenmayer/lSystems.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
from dataclasses import dataclass
|
||||||
|
import typing
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class LSytem:
|
||||||
|
name: str
|
||||||
|
startWord: str
|
||||||
|
productionRules: typing.Dict[str, str]
|
||||||
|
angel: float
|
||||||
|
|
||||||
|
LSystems = [
|
||||||
|
LSytem("AB a", "F", {"F": "F[+F]F[-F]F"}, 25.7),
|
||||||
|
LSytem("AB b", "F", {"F": "F[+F]F[-F][F]"}, 20.0),
|
||||||
|
LSytem("AB c", "F", {"F": "FF-[-F+F+F]+[+F-F-F]"}, 22.5),
|
||||||
|
LSytem("AB d", "X", {"X": "F[+X]F[-X]+X", "F": "FF"}, 20.0),
|
||||||
|
LSytem("AB e", "X", {"X": "F[+X][-X]FX", "F": "FF"}, 25.7),
|
||||||
|
LSytem("AB f", "X", {"X": "F-[[X]+X]+F[+FX]-X", "F": "FF"}, 22.5),
|
||||||
|
]
|
||||||
Reference in New Issue
Block a user