delete drawings

This commit is contained in:
2022-01-05 18:16:15 +01:00
parent 30caffb577
commit b509527b7c
4 changed files with 141 additions and 52 deletions

View File

@ -5,5 +5,6 @@ import time
turtle.tracer(0, 0) turtle.tracer(0, 0)
turtleObject = turtle.Turtle() turtleObject = turtle.Turtle()
turtleObject.hideturtle() turtleObject.hideturtle()
turtleObject.screen.colormode(255)
inputHelper.takeInput(turtleObject) inputHelper.takeInput(turtleObject)
turtleObject.screen.mainloop() turtleObject.screen.mainloop()

View File

@ -1,25 +1,48 @@
import turtle import turtle
from dataclasses import dataclass from dataclasses import dataclass
import lSystems
@dataclass @dataclass
class State: class State:
heading: float heading: float
position: turtle.Vec2D position: turtle.Vec2D
@dataclass
class DrawingInfo:
lSystem: lSystems.LSytem
position: turtle.Vec2D
rotation: float
color: any
scale: float
recursionDepth: int
drawings = []
class Drawer(): class Drawer():
def __init__(self, productionRules, angel, forwardDistance, startPosition, startRotation, turtle): def __init__(self, drawingInfo, turtleObject):
self.productionRules = productionRules self.startWord = drawingInfo.lSystem.startWord
self.angel = angel self.recursionDepth = drawingInfo.recursionDepth
self.forwardDistance = forwardDistance self.productionRules = drawingInfo.lSystem.productionRules
self.turtle = turtle self.angel = drawingInfo.lSystem.angel
self.turtle.setposition(startPosition) self.forwardDistance = drawingInfo.scale
self.turtle.setheading(startRotation) self.turtle = turtleObject
self.turtle.penup()
self.turtle.setposition(drawingInfo.position)
self.turtle.setheading(drawingInfo.rotation)
self.turtle.pendown() self.turtle.pendown()
self.turtle.pencolor(drawingInfo.color)
def storeEdges(self): def storeEdges(self):
pass pass
def draw(self, word, n): def pendown(self):
self.turtle.pendown()
def draw(self, word = None, n = None):
if n == None:
n = self.recursionDepth
if word == None:
word = self.startWord
turtleStates = [] turtleStates = []
if n == 0: if n == 0:
self.turtle.screen.update() self.turtle.screen.update()
@ -36,9 +59,11 @@ class Drawer():
case "[": case "[":
turtleStates.append(State(self.turtle.heading(), self.turtle.position())) turtleStates.append(State(self.turtle.heading(), self.turtle.position()))
case "]": case "]":
self.turtle.penup()
state = turtleStates.pop() state = turtleStates.pop()
self.turtle.setposition(state.position) self.turtle.setposition(state.position)
self.turtle.setheading(state.heading) self.turtle.setheading(state.heading)
self.pendown()
if character in self.productionRules: if character in self.productionRules:
self.draw(self.productionRules[character], n - 1) self.draw(self.productionRules[character], n - 1)
@ -54,8 +79,8 @@ class Edges:
return turtle.Vec2D(self.max[0], self.max[1]) return turtle.Vec2D(self.max[0], self.max[1])
class DrawerSimulation(Drawer): class DrawerSimulation(Drawer):
def __init__(self, productionRules, angel, forwardDistance, startPosition, startRotation, turtle): def __init__(self, drawingInfo, turtleObject):
super(DrawerSimulation, self).__init__(productionRules, angel, forwardDistance, startPosition, startRotation, turtle) super(DrawerSimulation, self).__init__(drawingInfo, turtleObject)
self.turtle.penup() self.turtle.penup()
self.edges = Edges() self.edges = Edges()
@ -66,18 +91,28 @@ class DrawerSimulation(Drawer):
elif koord > self.edges.max[i]: elif koord > self.edges.max[i]:
self.edges.max[i] = koord self.edges.max[i] = koord
def draw(turtleObject, lSystem, recursionDepth, middel, rotation, size): def pendown(self):
print(size) pass
simulatedDraw = DrawerSimulation(lSystem.productionRules, lSystem.angel, 1, turtle.Vec2D(0, 0), rotation, turtleObject)
simulatedDraw.draw(lSystem.startWord, recursionDepth) def draw(turtleObject, lSystem, recursionDepth, middle, rotation, size, color):
drawingInfo = DrawingInfo(lSystem, turtle.Vec2D(0, 0), rotation, color, 1, recursionDepth)
simulatedDraw = DrawerSimulation(drawingInfo, turtleObject)
simulatedDraw.draw()
maxVec = simulatedDraw.edges.maxVec() maxVec = simulatedDraw.edges.maxVec()
minVec = simulatedDraw.edges.minVec() minVec = simulatedDraw.edges.minVec()
distance = maxVec - minVec distance = maxVec - minVec
print(distance)
xScale = size[0] / distance[0] xScale = size[0] / distance[0]
yScale = size[1] / distance[1] yScale = size[1] / distance[1]
scale = yScale if xScale > yScale else xScale scale = yScale if xScale > yScale else xScale
pos = middel + (-minVec - distance * (1/2)) * scale pos = middle + (-minVec - distance * (1/2)) * scale
print(pos) drawingInfo.position = pos
actualDrawer = Drawer(lSystem.productionRules, lSystem.angel, scale, pos, rotation, turtleObject) drawingInfo.scale = scale
actualDrawer.draw(lSystem.startWord, recursionDepth) actualDrawer = Drawer(drawingInfo, turtleObject)
actualDrawer.draw()
drawings.append(drawingInfo)
def redraw(turtleObject):
turtleObject.clear()
for drawing in drawings:
drawer = Drawer(drawing, turtleObject)
drawer.draw()

View File

@ -4,48 +4,100 @@ import lSystems
def inputNum(inputType, description, rangeErrorMsg, minRange, maxRange, defaultValue = None): def inputNum(inputType, description, rangeErrorMsg, minRange, maxRange, defaultValue = None):
n: int n: int
inputError = True while True:
while inputError:
inputValue = input(description) inputValue = input(description)
try: try:
n = inputType(inputValue) n = inputType(inputValue)
inputError = n < minRange or n > maxRange
if inputError:
print(rangeErrorMsg)
else:
return n
except ValueError: except ValueError:
if inputValue == "" and defaultValue != None: if inputValue == "" and defaultValue != None:
return defaultValue return defaultValue
print("Fehler: keine gültige Zahl") print("Fehler: keine gültige Zahl")
continue
inputError = n < minRange or n > maxRange
if inputError:
print(rangeErrorMsg)
return n def inputColorError():
print("Fehler: ungültige Farbeingabe")
def inputColor(turtleObject, question, defaultValue = None):
while True:
defaultValueMsg = f" (Standartwert: {defaultValue})" if defaultValue != None else ""
inputValue = input(f"{question} RGB-Wert eingeben, wobei die Farben mit Leerzeichen getrennt werden, oder einen Tk-Farbnamen eingeben [0 0 0 - 255 255 255 oder Farben auf https://www.tcl.tk/man/tcl8.4/TkCmd/colors.html]{defaultValueMsg}: ")
if inputValue == "":
if defaultValue != None:
return defaultValue
inputColorError()
else:
oldPenColor = turtleObject.pencolor()
try:
color = tuple([int(color) for color in inputValue.split()])
turtleObject.pencolor(color)
turtleObject.pencolor(oldPenColor)
return color
except:
try:
turtleObject.pencolor(inputValue)
turtleObject.pencolor(oldPenColor)
return inputValue
except:
inputColorError()
def takeInput(turtleObject): def takeInput(turtleObject):
for i, lSystem in enumerate(lSystems.LSystems): inputValue = input("Bitte einen Befehl eingeben. h für Hilfe: ")
print(f"{i}: {lSystem.name}") match inputValue:
lSystemIndex = 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) case "h":
lSystem = lSystems.LSystems[lSystemIndex] print("""h: Hilfe anzeigen
recursionDepth = inputNum(int, "Rekursiontiefe des Lindenmayer-Systems eingeben [1-20] (Standartwert: 5): ", "Rekursionstiefe nicht im vorgegebenen Bereich.", 1, 20, 5) d: ein neues Lindenmayer-System zeichnen
rotation = inputNum(float, "Bitte die Rotation in Grad gegen den Uhrzeigersinn angeben, wobei 0° rechts ist (Standartwert: 90°): ", "nur Gradzahlen von 0 bis 360 werden akzeptiert.", 0, 360, 90) l: ein Lindenmayer-System löschen
inputError = True b: Hintergrundfarbe ändern
while inputError: q: Programm beenden""")
match input("Möchtest du das das Lindenmayer-System das ganze Fenster ausfüllt? [J/n]: ").lower(): case "d":
case "j"|"": for i, lSystem in enumerate(lSystems.LSystems):
inputError = False print(f"{i}: {lSystem.name}")
drawer.draw(turtleObject, lSystem, recursionDepth, turtle.Vec2D(0, 0), rotation, turtleObject.screen._window_size()) lSystemIndex = 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)
takeInput(turtleObject) lSystem = lSystems.LSystems[lSystemIndex]
case "n": recursionDepth = inputNum(int, "Rekursiontiefe des Lindenmayer-Systems eingeben [1-20] (Standartwert: 5): ", "Rekursionstiefe nicht im vorgegebenen Bereich.", 1, 20, 5)
inputError = False rotation = inputNum(float, "Bitte die Rotation in Grad gegen den Uhrzeigersinn angeben, wobei 0° rechts ist (Standartwert: 90°): ", "nur Gradzahlen von 0 bis 360 werden akzeptiert.", 0, 360, 90)
pos = [] inputError = True
def afterClick(vec): color = inputColor(turtleObject, "Welche Farbe soll das Lindenmayer-System haben?", "black")
pos.append(vec) while inputError:
if len(pos) == 2: match input("Möchtest du das das Lindenmayer-System das ganze Fenster ausfüllt? [J/n]: ").lower():
turtleObject.screen.onclick(None) case "j"|"":
size = pos[1] - pos[0] inputError = False
middel = pos[0] + (1/2) * size drawer.draw(turtleObject, lSystem, recursionDepth, turtle.Vec2D(0, 0), rotation, turtleObject.screen._window_size(), color)
print(middel)
size = turtle.Vec2D(abs(size[0]), abs(size[1]))
drawer.draw(turtleObject, lSystem, recursionDepth, middel, rotation, size)
takeInput(turtleObject) takeInput(turtleObject)
case "n":
inputError = False
pos = []
def afterClick(vec):
pos.append(vec)
if len(pos) == 2:
turtleObject.screen.onclick(None)
size = pos[1] - pos[0]
middle = pos[0] + (1/2) * size
size = turtle.Vec2D(abs(size[0]), abs(size[1]))
drawer.draw(turtleObject, lSystem, recursionDepth, middle, rotation, size, color)
takeInput(turtleObject)
turtleObject.screen.onclick(lambda x, y: afterClick(turtle.Vec2D(x, y))) turtleObject.screen.onclick(lambda x, y: afterClick(turtle.Vec2D(x, y)))
case _:
print("Bitte j oder n eingeben")
case "b":
turtleObject.screen.bgcolor(inputColor(turtleObject, "Hintergrundfarbe eingeben"))
case "q":
quit()
case "l":
if len(drawer.drawings) == 0:
print("Es gibt nichts, was man löschen könnte.")
else:
for i, drawing in enumerate(drawer.drawings):
print(f"{i}: {drawing.lSystem.name} Position: {drawing.position}")
iDelete = inputNum(int, "Nummer des zu löschenden Zeichnung eingeben: ", "Es gibt keine Zeichnung mit dieser Nummer", 0, len(drawer.drawings) - 1)
del drawer.drawings[iDelete]
drawer.redraw(turtleObject)
case _:
print("unbekannter Befehl")
if inputValue != "d":
takeInput(turtleObject)

View File

@ -15,4 +15,5 @@ LSystems = [
LSytem("AB d", "X", {"X": "F[+X]F[-X]+X", "F": "FF"}, 20.0), 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 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), LSytem("AB f", "X", {"X": "F-[[X]+X]+F[+FX]-X", "F": "FF"}, 22.5),
LSytem("Drachenkurve", "FX", {"X": "X+YF+", "Y": "-FX-Y"}, 90.0),
] ]