delete drawings
This commit is contained in:
@ -5,5 +5,6 @@ import time
|
||||
turtle.tracer(0, 0)
|
||||
turtleObject = turtle.Turtle()
|
||||
turtleObject.hideturtle()
|
||||
turtleObject.screen.colormode(255)
|
||||
inputHelper.takeInput(turtleObject)
|
||||
turtleObject.screen.mainloop()
|
||||
|
||||
@ -1,25 +1,48 @@
|
||||
import turtle
|
||||
from dataclasses import dataclass
|
||||
import lSystems
|
||||
|
||||
@dataclass
|
||||
class State:
|
||||
heading: float
|
||||
position: turtle.Vec2D
|
||||
|
||||
@dataclass
|
||||
class DrawingInfo:
|
||||
lSystem: lSystems.LSytem
|
||||
position: turtle.Vec2D
|
||||
rotation: float
|
||||
color: any
|
||||
scale: float
|
||||
recursionDepth: int
|
||||
|
||||
drawings = []
|
||||
|
||||
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.setposition(startPosition)
|
||||
self.turtle.setheading(startRotation)
|
||||
def __init__(self, drawingInfo, turtleObject):
|
||||
self.startWord = drawingInfo.lSystem.startWord
|
||||
self.recursionDepth = drawingInfo.recursionDepth
|
||||
self.productionRules = drawingInfo.lSystem.productionRules
|
||||
self.angel = drawingInfo.lSystem.angel
|
||||
self.forwardDistance = drawingInfo.scale
|
||||
self.turtle = turtleObject
|
||||
self.turtle.penup()
|
||||
self.turtle.setposition(drawingInfo.position)
|
||||
self.turtle.setheading(drawingInfo.rotation)
|
||||
self.turtle.pendown()
|
||||
self.turtle.pencolor(drawingInfo.color)
|
||||
|
||||
def storeEdges(self):
|
||||
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 = []
|
||||
if n == 0:
|
||||
self.turtle.screen.update()
|
||||
@ -36,9 +59,11 @@ class Drawer():
|
||||
case "[":
|
||||
turtleStates.append(State(self.turtle.heading(), self.turtle.position()))
|
||||
case "]":
|
||||
self.turtle.penup()
|
||||
state = turtleStates.pop()
|
||||
self.turtle.setposition(state.position)
|
||||
self.turtle.setheading(state.heading)
|
||||
self.pendown()
|
||||
if character in self.productionRules:
|
||||
self.draw(self.productionRules[character], n - 1)
|
||||
|
||||
@ -54,8 +79,8 @@ class Edges:
|
||||
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)
|
||||
def __init__(self, drawingInfo, turtleObject):
|
||||
super(DrawerSimulation, self).__init__(drawingInfo, turtleObject)
|
||||
self.turtle.penup()
|
||||
self.edges = Edges()
|
||||
|
||||
@ -66,18 +91,28 @@ class DrawerSimulation(Drawer):
|
||||
elif koord > self.edges.max[i]:
|
||||
self.edges.max[i] = koord
|
||||
|
||||
def draw(turtleObject, lSystem, recursionDepth, middel, rotation, size):
|
||||
print(size)
|
||||
simulatedDraw = DrawerSimulation(lSystem.productionRules, lSystem.angel, 1, turtle.Vec2D(0, 0), rotation, turtleObject)
|
||||
simulatedDraw.draw(lSystem.startWord, recursionDepth)
|
||||
def pendown(self):
|
||||
pass
|
||||
|
||||
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()
|
||||
minVec = simulatedDraw.edges.minVec()
|
||||
distance = maxVec - minVec
|
||||
print(distance)
|
||||
xScale = size[0] / distance[0]
|
||||
yScale = size[1] / distance[1]
|
||||
scale = yScale if xScale > yScale else xScale
|
||||
pos = middel + (-minVec - distance * (1/2)) * scale
|
||||
print(pos)
|
||||
actualDrawer = Drawer(lSystem.productionRules, lSystem.angel, scale, pos, rotation, turtleObject)
|
||||
actualDrawer.draw(lSystem.startWord, recursionDepth)
|
||||
pos = middle + (-minVec - distance * (1/2)) * scale
|
||||
drawingInfo.position = pos
|
||||
drawingInfo.scale = scale
|
||||
actualDrawer = Drawer(drawingInfo, turtleObject)
|
||||
actualDrawer.draw()
|
||||
drawings.append(drawingInfo)
|
||||
|
||||
def redraw(turtleObject):
|
||||
turtleObject.clear()
|
||||
for drawing in drawings:
|
||||
drawer = Drawer(drawing, turtleObject)
|
||||
drawer.draw()
|
||||
|
||||
@ -4,48 +4,100 @@ import lSystems
|
||||
|
||||
def inputNum(inputType, description, rangeErrorMsg, minRange, maxRange, defaultValue = None):
|
||||
n: int
|
||||
inputError = True
|
||||
while inputError:
|
||||
while True:
|
||||
inputValue = input(description)
|
||||
try:
|
||||
n = inputType(inputValue)
|
||||
inputError = n < minRange or n > maxRange
|
||||
if inputError:
|
||||
print(rangeErrorMsg)
|
||||
else:
|
||||
return n
|
||||
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
|
||||
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):
|
||||
for i, lSystem in enumerate(lSystems.LSystems):
|
||||
print(f"{i}: {lSystem.name}")
|
||||
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)
|
||||
lSystem = lSystems.LSystems[lSystemIndex]
|
||||
recursionDepth = inputNum(int, "Rekursiontiefe des Lindenmayer-Systems eingeben [1-20] (Standartwert: 5): ", "Rekursionstiefe nicht im vorgegebenen Bereich.", 1, 20, 5)
|
||||
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)
|
||||
inputError = True
|
||||
while inputError:
|
||||
match input("Möchtest du das das Lindenmayer-System das ganze Fenster ausfüllt? [J/n]: ").lower():
|
||||
case "j"|"":
|
||||
inputError = False
|
||||
drawer.draw(turtleObject, lSystem, recursionDepth, turtle.Vec2D(0, 0), rotation, turtleObject.screen._window_size())
|
||||
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]
|
||||
middel = pos[0] + (1/2) * size
|
||||
print(middel)
|
||||
size = turtle.Vec2D(abs(size[0]), abs(size[1]))
|
||||
drawer.draw(turtleObject, lSystem, recursionDepth, middel, rotation, size)
|
||||
inputValue = input("Bitte einen Befehl eingeben. h für Hilfe: ")
|
||||
match inputValue:
|
||||
case "h":
|
||||
print("""h: Hilfe anzeigen
|
||||
d: ein neues Lindenmayer-System zeichnen
|
||||
l: ein Lindenmayer-System löschen
|
||||
b: Hintergrundfarbe ändern
|
||||
q: Programm beenden""")
|
||||
case "d":
|
||||
for i, lSystem in enumerate(lSystems.LSystems):
|
||||
print(f"{i}: {lSystem.name}")
|
||||
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)
|
||||
lSystem = lSystems.LSystems[lSystemIndex]
|
||||
recursionDepth = inputNum(int, "Rekursiontiefe des Lindenmayer-Systems eingeben [1-20] (Standartwert: 5): ", "Rekursionstiefe nicht im vorgegebenen Bereich.", 1, 20, 5)
|
||||
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)
|
||||
inputError = True
|
||||
color = inputColor(turtleObject, "Welche Farbe soll das Lindenmayer-System haben?", "black")
|
||||
while inputError:
|
||||
match input("Möchtest du das das Lindenmayer-System das ganze Fenster ausfüllt? [J/n]: ").lower():
|
||||
case "j"|"":
|
||||
inputError = False
|
||||
drawer.draw(turtleObject, lSystem, recursionDepth, turtle.Vec2D(0, 0), rotation, turtleObject.screen._window_size(), color)
|
||||
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)
|
||||
|
||||
@ -15,4 +15,5 @@ LSystems = [
|
||||
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),
|
||||
LSytem("Drachenkurve", "FX", {"X": "X+YF+", "Y": "-FX-Y"}, 90.0),
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user