Ich versuche, ein physikalisches Simulationsprogramm zu schreiben. Im Prinzip funktioniert es schon gut, nur das GUI macht nicht richtig mit.
Selbst wenn die Subroutine Simulation 1000 Zyklen durchläuft, werden die 1000 Zeichnungen erst am Schluss auf einmal geplottet, die after Funktion sorgt zwar für eine Zeitverzögerung, aber gezeichnet wird erst ganz am Schluss.
Ich verstehe das nicht ganz, jede pack anweisung schiebt die zu zeichnende Linie doch in eine Queue, wo sie unabhängig vom Programmablauf gezeichnet wird? Warum wartet das Gui mit dem zeichnen, bis das Programm durch alle Zyklen durch ist, anstatt sofort zu loszulegen ?
Code: Alles auswählen
import time
#import datetime
import os
import re
import math
from tkinter import *
# Spezifikation der Variablen
G=6.672*10 ** (-11)
LBL=[]
M=[]
R=dict()
pstart=dict()
pz=lz=oz=Anzahl_Objekte=zeit=lfz=0
t_alt=-1
P=[]
Kalibrierung=0
R[0]=0
V=[]
O=[]
F=[]
ROTATION=[]
BM=[]
BP=[]
BV=[]
S=[]
NAME=[]
LINIE=[]
SKALIERUNG=[]
ZOOM=[]
UPS=[]
ZK=0
Z=0
BV_Schritt=1
counter=1
Zyklen=0
lfz=0
PROJEKTION="Zentralprojektion"
class Data:
def __init__(self,objnr,txt="",x=0,y=0,z=0):
self.objnr=objnr
self.txt=txt
self.x=x
self.y=y
self.z=z
def Drehen(self,zeit,ups,n1,n2,n3):
u=ups*zeit
w=2*math.pi*(u - int(u))
cos=math.cos(w)
sin=math.sin(w)
a1=n1**2*(1-cos) + cos
a2=n1*n2*(1-cos) + n3*sin
a3=n1*n3*(1-cos) - n2*sin
b1=n1*n2*(1-cos) - n3*sin
b2=n2**2*(1-cos) + cos
b3=n2*n3*(1-cos) + n1*sin
c1=n1*n3*(1-cos)+ n2*sin
c2=n2*n3*(1-cos)-n1*sin
c3=n3**2*(1-cos) + cos
xx=self.x * a1 + self.y * b1 + self.z * c1
yy=self.x * a2 + self.y * b2 + self.z * c2
zz=self.x * a3 + self.y * b3 + self.z * c3
self.x=xx
self.y=yy
self.z=zz
def Laden(fn):
global LBL, pstart, M, R, pz, lz, oz, zeit, lfz, t_alt, P
global R, V, O, F, ROTATION, BM, BP, BV, S, NAME, LINIE, SKALIERUNG, ZOOM
global UPS, ZK, Z, PROJEKTION, Anzahl_Objekte, BV_Schritt
Anzahl_Objekte=counter=Zyklen=0
BM=[]
BV=[]
BP=[]
SKALIERUNG=[]
P=[]
LINIE=[]
ROTATION=[]
O=[]
F=[]
LBL=[]
pz=0
lz=0
f=open(fn,"r")
for l in f:
zeile=l.split()
if zeile[1] == "P":
t0=int(zeile[0])
t2=float(zeile[2])
t3=float(zeile[3])
t4=float(zeile[4])
P.append(Data(t0, "", t2, t3, t4))
if t_alt != t0:
R[t0]=0
pstart[t0] = pz
t_alt = t0
pz = pz + 1
# Ermittle max Radius für Kollisionsdetektor
betrag=(t2 ** 2 + t3 ** 2 + t4 ** 2)**0.5
if R[t0]< betrag : R[t0]=betrag
elif zeile[1] == "NAME": NAME.append(Data(0, zeile[2]))
elif zeile[1] == "L":
t0=int(zeile[0])
LINIE.append(Data(int(zeile[0]), "", int(zeile[2]) + pstart[t0], int(zeile[3]) + pstart[t0]))
lz=lz+1
elif zeile[1] == "F": F.append(Data(0, zeile[2]))
elif zeile[1] == "ZOOM": ZOOM = float(zeile[2])
elif zeile[1] == "ZK": ZK = float(zeile[2])
elif zeile[1] == "Z": Z = float(zeile[2])
elif zeile[1] == "V": V.append(Data(int(zeile[0]), "", float(zeile[2]), float(zeile[3]), float(zeile[4])))
elif zeile[1] == "O":
Anzahl_Objekte += 1
t0=int(zeile[0])
O.append(Data(t0, "", float(zeile[2]), float(zeile[3]), float(zeile[4])))
LBL.extend(["Info_" + zeile[0]])
LblPos=28+ 100 * t0
LBL[t0] = Label(master=master, bg='#FFCFC9', text=zeile[0])
LBL[t0].place(x=1000, y=LblPos, width=200, height=99)
elif zeile[1] == "ROTATION": ROTATION.append(Data(0, "", float(zeile[2]), float(zeile[3]), float(zeile[4])))
elif zeile[1] == "UPS": UPS.append(Data(float(zeile[2])))
elif zeile[1] == "M": M.append(Data(float(zeile[2])))
elif zeile[1] == "S": S.append(Data(int(zeile[0]), "", float(zeile[2]), float(zeile[3]), float(zeile[4])))
elif zeile[1] == "BP": BP.append(Data(0, "", float(zeile[2]),float(zeile[3]),float(zeile[4])))
elif zeile[1] == "BM": BM.append(Data(0, "", float(zeile[2]), float(zeile[3]), float(zeile[4])))
elif zeile[1] == "BV": BV.append(Data(0, "", float(zeile[2]), float(zeile[3]), float(zeile[4])))
elif zeile[1] == "SKALIERUNG": SKALIERUNG.append(Data(0, "", float(zeile[2]), float(zeile[3]), float(zeile[4])))
elif zeile[1] == "BVS": BV_Schritt = float(zeile[2])
elif zeile[1] == "PROJEKTION": PROJEKTION = zeile[2]
f.close()
update_Info()
def Zyklus_berechnen():
global LBL, pstart, M, R, pz, lz, oz, zeit, lfz, t_alt, Zyklen, Kollisionswarnung
global R, V, O, F, BP, BV, BM, ROTATION, S, NAME, LINIE, SKALIERUNG, ZOOM, P
global UPS, ZK, Z, PROJEKTION, Anzahl_Objekte, BV_Schritt, counter
# Update Anzahl Zyklen Label
counter+=1
v=(BV[0].x**2 + BV[0].y**2 + BV[0].z**2)**0.5
txt="Anzahl Zyklen: " + str(counter) + " BV: " + str(v)
LabelZyklen.config(text=txt)
# Ermittlung der Abstände und Kraftvektoren
z1=0
while z1 < Anzahl_Objekte:
z2=0
if counter == 1: break
while z2 < Anzahl_Objekte:
# Sonderfall für nur ein Objekt
if Anzahl_Objekte==1:
O[0].x += Z * V[0].x
O[0].y += Z * V[0].y
O[0].z += Z * V[0].z
betrag=(V[0].x**2 + V[0].y**2 + V[0].z**2)**0.5
txt=NAME[0].txt + " \nV=" + str(betrag) + " m/s"
LBL[0].config(text=txt)
# Änderung der Beobachterposition
BP[0].x += BV[0].x * Z
BP[0].y += BV[0].y * Z
BP[0].z += BV[0].z * Z
update_Info()
z2=z2+1
continue
elif z2<=z1:
z2=z2+1
continue
# Ermittlung des Kraftvektors zwischen den Objekten
x=O[z2].x - O[z1].x
y=O[z2].y - O[z1].y
z=O[z2].z - O[z1].z
# Normiere den Kraftvektor
betrag=(x ** 2 + y ** 2 + z ** 2)**0.5
if betrag == 0:
x=y=z=0
else:
x=x/betrag
y=y/betrag
z=z/betrag
# Kollisionsprüfung
if Kollisionswarnung >0 and betrag <= R[z1] + R[z2]:
line="Achtung, Kollision Objekt " + str(z1) + " und " + str(z2) + "\nTrotzdem fortfaheren?"
if Bestätigung(line) == "n": return(0)
if Bestätigung("Weitere Kollisionswarnungen unterdrücken ?") == "j":
Kollisionswarnung=0
# Berechnung der Anziehungskraft
if betrag > 0:
Kraft = (G * M[z1].objnr * M[z2].objnr)/betrag ** 2
else:
Kraft=0
line="Kraft zwischen Objekt " + str(z1) + " und Objekt " + str(z2) + " : " + str(Kraft) + "\n"
log.write(line)
line="Kraftvektor: " + str(x) + " , " + str(y) + " , " + str(z) + "\n"
log.write(line)
# Berechnung der resultierenden Beschleunigungen
if M[z1].objnr > 0: a1 = Kraft / M[z1].objnr
else: a1=0
v1 = Z * a1
if M[z2].objnr > 0: a2 = -1 * Kraft / M[z2].objnr
else: a2=0
v2 = Z * a2
line="a1,v1,a2,v2,zeit: " + str(a1) + "," + str(v1) + "," + str(a2) + "," + str(v2) + "," + "\n"
log.write(line)
#andrucken der aktuellen Daten
txt=NAME[z1].txt + " \nV=" + str(v1) + " m/s\na=" + str(a1) + "\nMitte-Mitte Abstand zu " + NAME[z2].txt + " =" + str(betrag)
LBL[z1].config(text=txt)
txt=NAME[z2].txt + " \nV=" + str(v2) + " m/s\na=" + str(a2) + "\nMitte-Mitte Abstand zu " + NAME[z1].txt + " =" + str(betrag)
LBL[z2].config(text=txt)
# Änderung der Ortsvektoren unter Annahme konstanter Kraft
O[z1].x += Z * V[z1].x + x * 0.5 * a1 * Z ** 2
O[z1].y += Z * V[z1].y + y * 0.5 * a1 * Z ** 2
O[z1].z += Z * V[z1].z + z * 0.5 * a1 * Z ** 2
O[z2].x += Z * V[z2].x + x * 0.5 * a2 * Z ** 2
O[z2].y += Z * V[z2].y + y * 0.5 * a2 * Z ** 2
O[z2].z += Z * V[z2].z + z * 0.5 * a2 * Z ** 2
# Änderung der Geschwindigekeitsvektoren
V[z1].x += v1 * x
V[z1].y += v1 * y
V[z1].z += v1 * z
V[z2].x += v2 * x
V[z2].y += v2 * y
V[z2].z += v2 * z
#Schreibe Objektdaten in Logfile
line = str(z1) + " O " +str(O[z1].x) + " " + str(O[z1].y) + " " + str(O[z1].z) + "\n"
log.write(line)
line =str(z1) + " V " +str(V[z1].x) + " " + str(V[z1].y) + " " + str(V[z1].z) + "\n"
log.write(line)
line = str(z2) + " O " +str(O[z2].x) + " " + str(O[z2].y) + " " + str(O[z2].z) + "\n"
log.write(line)
line = str(z2) + " V " +str(V[z2].x) + " " + str(V[z2].y) + " " + str(V[z2].z) + "\n"
log.write(line)
z2=z2+1
z1=z1+1
lfz+=Z
laufzeit=str(lfz)
line="Laufzeit " + laufzeit + "\n\n"
log.write(line)
#Anpassung der Punkte
PP=[]
p=0
while p < pz:
objnr=P[p].objnr
# Drehung der Objekte
if UPS[objnr].objnr != 0: P[p].Drehen(lfz,UPS[objnr].objnr,ROTATION[objnr].x,ROTATION[objnr].y,ROTATION[objnr].z)
# Normierung auf das Beobachterkooordinatensystem
x=(P[p].x+O[objnr].x-BP[0].x)*BM[0].x+(P[p].y+O[objnr].y-BP[0].y)*BM[0].y+(P[p].z+O[objnr].z-BP[0].z)*BM[0].z
y=(P[p].x+O[objnr].x-BP[0].x)*BM[1].x+(P[p].y+O[objnr].y-BP[0].y)*BM[1].y+(P[p].z+O[objnr].z-BP[0].z)*BM[1].z
z=(P[p].x+O[objnr].x-BP[0].x)*BM[2].x+(P[p].y+O[objnr].y-BP[0].y)*BM[2].y+(P[p].z+O[objnr].z-BP[0].z)*BM[2].z
if PROJEKTION=="Parallelprojektion":
x=int(x * Kalibrierung * ZOOM) + 400
y=400 - int(y * Kalibrierung * ZOOM)
PP.append(Data(objnr, "", x, y, z))
elif PROJEKTION=="Projektion_auf_Kugel":
betrag=(x**2 + y**2 + z**2)**0.5
x=int((x * Kalibrierung * ZOOM)/betrag) + 400
y=400 - int((y * Kalibrierung * ZOOM)/betrag)
PP.append(Data(objnr, "", x, y, z))
else:
if z != 0:
x=int((x/z) * Kalibrierung * ZOOM + 400)
y=400 - int((y/z) * Kalibrierung * ZOOM)
else: x = y = -1000
PP.append(Data(objnr, "", int(x), int(y), z))
line="Punkt " + str(p) + "--> z=" + str(z) +" Bildtafel:" + str(x) + " " +str(y) + "\n"
log.write(line)
p = p + 1
#Zeichnen der Linien
l=0
while l < lz:
objnr=int(LINIE[l].objnr)
p1=LINIE[l].x
p2=LINIE[l].y
l=l+1
# Überspringe Zeilen mit Start- und Endpunkt hinter dem Betrachter
if PP[p1].z <= 0 and PP[p2].z <= 0: continue
# Setzen des Mindestabstandes von einem Punkt
if PP[p1].x == PP[p2].x: PP[p1].x += 1
if PP[p1].y == PP[p2].y: PP[p2].y += 1
w.create_line(PP[p1].x, PP[p1].y, PP[p2].x, PP[p2].y, fill=F[objnr].txt , width=1)
w.pack()
def Kalibrierung():
global Kalibrierung, pz, P, BM, O, BP, PROJEKTION, log
max=p=0
while p < pz:
objnr=P[p].objnr
x=(P[p].x+O[objnr].x-BP[0].x)*BM[0].x+(P[p].y+O[objnr].y-BP[0].y)*BM[0].y+(P[p].z+O[objnr].z-BP[0].z)*BM[0].z
y=(P[p].x+O[objnr].x-BP[0].x)*BM[1].x+(P[p].y+O[objnr].y-BP[0].y)*BM[1].y+(P[p].z+O[objnr].z-BP[0].z)*BM[1].z
z=(P[p].x+O[objnr].x-BP[0].x)*BM[2].x+(P[p].y+O[objnr].y-BP[0].y)*BM[2].y+(P[p].z+O[objnr].z-BP[0].z)*BM[2].z
if PROJEKTION == "Parallelprojektion":
xx=abs(x)
yy=abs(y)
elif PROJEKTION == "Projektion_auf_Kugel":
betrag=(x**2 + y**2 + z**2)**0.5
xx=abs(x/betrag)
yy=abs(y/betrag)
elif PROJEKTION == "Zentralprojektion":
if z != 0:
xx=abs(x/z)
yy=abs(y/z)
else: xx=yy=0
if xx > max : max=xx
if yy > max : max=yy
line="x="+str(x)+" y="+str(y)+" z=" + str(z)+ " xx="+str(xx)+" YY="+str(yy)+ " max=" + str(max) + "\n"
log.write(line)
p += 1
if max != 0: Kalibrierung=200/max
else: Kalibrierung = 1
line="Projektionsart: " + PROJEKTION + "Kalibrierungsfakror: " + str(Kalibrierung) + "\n"
log.write(line)
def Zeit_anpassen(Zeit):
if Zeit> 31536000:
Faktor=1/31536000
Einheit="Jahre"
elif Zeit> 86400:
Faktor=1/86400
Einheit = "Tage"
elif Zeit > 3600:
Faktor=1-3600
Einheit = "Stunden"
else:
Faktor=1
Einheit = "Sekunden"
return(Zeit * Faktor,Einheit)
def update_Info():
global BV, BM, BP
Faktor = 1
Einheit = " m"
if abs(BP[0].x) > 1000 and abs(BP[0].y) > 1000 and abs(BP[0].z) > 1000:
Faktor = 0.001
Einheit = " Km"
elif abs(BP[0].x) < 0.001 and abs(BP[0].y) < 0.001 and abs(BP[0].z) < 0.001:
Faktor = 1000000
Einheit = " μm"
elif abs(BP[0].x) < 1 and abs(BP[0].y) < 1 and abs(BP[0].z) < 1:
Faktor = 1000
Einheit = " mm"
x='{:.2f}'.format(BP[0].x * Faktor)
y='{:.2f}'.format(BP[0].y * Faktor)
z='{:.2f}'.format(BP[0].z * Faktor)
txt="Position: " + x + "/" + y + "/" + z + Einheit
Label_BP.config(text=txt)
betrag=(BV[0].x**2 + BV[0].y**2 + BV[0].z**2)**0.5
Faktor = 1
Einheit = " m/Sek"
if betrag > 1000:
Faktor = 0.001
Einheit = " Km/Sek"
elif betrag < 0.001:
Faktor = 1000000
Einheit = " μm/Sek"
elif betrag < 1:
Faktor = 1000
Einheit = " mm/Sek"
txt="Geschwindigkeit " + '{:.2f}'.format(betrag * Faktor) + Einheit
Label_BV.config(text=txt)
txt="Blickrichtung: " + '{:.2f}'.format(BM[2].x) + "/" + '{:.2f}'.format(BM[2].y) + "/" + '{:.2f}'.format(BM[2].z)
txt=txt + "\n" + "Horizont : " + '{:.2f}'.format(BM[1].x) + "/" + '{:.2f}'.format(BM[1].y) + "/" + '{:.2f}'.format(BM[1].z)
Label_BM.config(text=txt)
def Beobachter_drehen(Achse,Richtung):
n1=n2=n3=0
ups=1/360
if Achse == "x": n1 = 1
elif Achse == "y": n2 = 1
elif Achse == "z": n3 = 1
if Richtung == "links": ups = -ups
BM[0].Drehen(1, ups, n1, n2, n3)
BM[1].Drehen(1, ups, n1, n2, n3)
BM[2].Drehen(1, ups, n1, n2, n3)
x='{:3.2f}'.format(BM[2].x)
y='{:3.2f}'.format(BM[2].y)
z='{:3.2f}'.format(BM[2].z)
a='{:3.2f}'.format(BM[0].x)
b='{:3.2f}'.format(BM[0].y)
c='{:3.2f}'.format(BM[0].z)
txt="Blickrichtung: " + x + "/" + y + "/" + z
txt=txt + "\n" + "Horizont : " + a + "/" + b + "/" + c +"/"
Label_BM.config(text=txt)
def Beobachter_bewegen(Achse,Richtung):
global BV, BV_Schritt
if Richtung == "+": Schritt = BV_Schritt
elif Richtung == "-": Schritt = - BV_Schritt
if Achse == "x": BV[0].x += Schritt
elif Achse == "y": BV[0].y += Schritt
elif Achse == "z": BV[0].z += Schritt
v=str((BV[0].x**2 + BV[0].y**2 + BV[0].z**2)**0.5)
txt="Beobachtertempo: " + v
Label_BV.config(text=txt)
def neu_laden():
global fn
Data.Laden(fn)
def löschen():
w.delete("all")
def Info(txt):
info = Tk()
T = Text(info, height=2, width=80)
T.pack()
T.insert(END, txt)
T.mainloop()
def Bestätigung(txt):
# Öffnet Ein Auswahlfeld für ja oder nein
Eingabe = Toplevel()
Eingabe.geometry('300x100+0+0')
v = StringVar()
Label(Eingabe,text=txt,justify = LEFT,padx = 50).pack()
Radiobutton(Eingabe,text="Ja",indicatoron = 0,width = 40,padx = 50,variable=v,command=Eingabe.quit,value="j").pack(anchor=W)
Radiobutton(Eingabe,text="Nein",indicatoron = 0,width =40,padx = 50,variable=v,command=Eingabe.quit,value="n").pack(anchor=W)
Eingabe.mainloop()
antwort=v.get()
Eingabe.destroy()
return(antwort)
def Auswahl(Labels):
# Öffnet Ein Auswahlfeld für eine Liste von Argumenten
Eingabe = Toplevel()
v = StringVar()
Label(Eingabe,text="Bitte wählen",justify = LEFT,padx = 50).pack()
for label in Labels:
Radiobutton(Eingabe,text=label,indicatoron = 0,width = 50,padx = 50,variable=v,command=Eingabe.quit,value=label).pack(anchor=W)
Eingabe.mainloop()
antwort=v.get()
Eingabe.destroy()
return(antwort)
def Datei_wählen(match):
# Zeigt Dateien an, auf die match passt, lässt eine auswählen, und gibt den Dateinahmen als Returnwert zurück
datei = Toplevel()
v = IntVar()
V=[]
x=0
Label(datei,text="""Bitte Datei auswählen:""",justify = LEFT,padx = 50).pack()
for txt in os.listdir("Simulator"):
if re.search(match,txt):
V.append(txt)
Radiobutton(datei,
text=txt,
indicatoron = 0,
width = 50,
padx = 50,
variable=v,
command=datei.quit,
value=x).pack(anchor=W)
x=x+1
mainloop()
fn=V[v.get()]
datei.destroy()
return(fn)
def Eingabe(Labels):
# Öffnet Ein textfeld zur Eingabe beliebig vieler Parameter, Ergebnis wird als Liste zurückgegeben
entries=[]
resultat=[]
Eingabe = Toplevel()
for field in Labels:
L=field.split("=")
row = Frame(Eingabe)
lab = Label(row, width=60, text=L[0], anchor='w')
ent = Entry(row)
ent.insert(10,L[1])
row.pack(side=TOP, fill=X, padx=5, pady=5)
lab.pack(side=LEFT)
ent.pack(side=RIGHT, expand=YES, fill=X)
entries.append((L[0], ent))
#Eingabe.bind('<Return>', (lambda event))
b1 = Button(Eingabe, text='Fertig',command=(Eingabe.quit))
b1.pack(side=LEFT, padx=5, pady=5)
Eingabe.mainloop()
for entry in entries:
field = entry[0]
text = entry[1].get()
resultat.append(text)
Eingabe.destroy()
return(resultat)
def Neue_Objekte() :
L=[]
L=Eingabe(["Name des neuen Objekts="])
obj='Simulator/' + L[0] + '_obj.txt'
#Prüfe Existenz von Verzeichnis
if (os.path.isdir('Simulator') == False):
os.mkdir('Simulator')
#Prüfe Existenz von Datei
if (os.path.isfile(obj)):
if Bestätigung("Datei existiert, soll sie überschrieben werden ?") == "n":
return(1)
f=open(obj,"w+")
form=Auswahl(["Kreis","Kugel","Quader","Pyramide","Freie Modelierung"])
if ('Kugel' in form):
L=Eingabe(["Tiefe in Meter=1","Breite in Meter=1","Höhe in Meter=1","Teilung=10"])
t=float(L[0])
b=float(L[1])
h=float(L[2])
teilung=int(L[3])
#Verschachtelte Schleife, um die Kugel zu konstruieren
if teilung == "": teilung=30
s=2 * math.pi / teilung
wxz=0
p=0
while wxz < teilung:
wxy=0
while wxy < teilung:
p=teilung * wxz + wxy
y=0.5 * math.sin(s * wxy) * h
x=0.5 * math.cos(s * wxy) * math.cos(wxz) * b
z=0.5 * math.sin(s * wxz) * math.sin(wxy) * t
line= "P " + str(x) + " " + str(y) + " " + str(z) + "\n"
if wxy>0: line=line + " L " + str(p-1) + " " + str(p) + "\n"
else: line=line + " L " + str(p) + " " + str(p+teilung -1) + "\n"
if wxz > 0:
line=line + " L " + str(p) + " " + str(p - teilung) + "\n"
f.write(line)
wxy += 1
wxz += 1
elif ('Kreis' in form):
L=Eingabe(["Breite in Meter=1","Höhe in Meter=1","Teilung=10"])
b=float(L[0])
h=float(L[1])
teilung=int(L[2])
# Schleife, um den Kreis zu konstruieren
if teilung == "": teilung=30
s=2 * math.pi / teilung
p=0
while p < teilung:
y=0.5 * math.sin(s * p) * h
x=0.5 * math.cos(s * p) * b
line= "P " + str(x) + " " + str(y) + " 0\n"
if p>0: line=line + " L " + str(p-1) + " " + str(p) + "\n"
f.write(line)
p += 1
line=line + " L 0 " + str(p-1) + "\n"
f.write(line)
elif('Quader' in form):
L=Eingabe(["Tiefe in Meter=1","Breite in Meter=1","Höhe in Meter=1"])
t=str(float(L[0])/2)
b=str(float(L[1])/2)
h=str(float(L[2])/2)
line= "P -" + b + " -" + h + " -" + t + "\n"
line= line + "P -" + b + " -" + h + " " + t + "\n"
line= line + "P " + b + " -" + h + " " + t + "\n"
line= line + "P " + b + " -" + h + " -" + t + "\n"
line= line + "P -" + b + " " + h + " -" + t + "\n"
line= line + "P -" + b + " " + h + " " + t + "\n"
line= line + "P " + b + " " + h + " -" + t + "\n"
line= line + "P " + b + " " + h + " " + t + "\n"
line= line + "L 0 1\nL 1 2\nL 2 3\nL 3 0\n"
line= line + "L 4 5\nL 5 6\nL 6 7\nL 7 4\n"
line= line + "L 0 4\nL 1 5\nL 2 6\nL 3 7\n"
f.write(line)
elif('Pyramide' in form):
L=Eingabe(["Tiefe in Meter=1","Breite in Meter=1","Höhe in Meter=1"])
t=float(L[0])
b=float(L[1])
h=float(L[2])
line= "P " + str(-0.5*b) + " " + str(-0.25*h) + " " + str(-0.5*t) + "\n"
line= line + "P " + str(0.5*b) + " " + str(-0.25*h) + " " + str(-0.5*t) + "\n"
line= line + "P " + str(0.5*b) + " " + str(-0.25*h) + " " + str(0.5*t) + "\n"
line= line + "P " + str(-0.5*b) + " " + str(-0.25*h) + " " + str(0.5*t) + "\n"
line= line + "P 0 " + str(0.75*h) + " 0\n"
line= line + "L 0 1\nL 1 2\nL 2 3\nL 3 0\n"
line= line + "L 0 4\nL 1 4\nL 2 4\nL 3 4\n"
f.write(line)
elif('Freie Modelierung' in form):
# Wird nur zur Anpassung der Punkte genutzt, um den Schwerpunkt zu 0/0/0 zu verschieben
L=Eingabe(["Schwerpunkt des Objekts X-Achse=0", "Schwerpunkt des Objekts Y-Achse=0", "Schwerpunkt des Objekts Z-Achse=0"])
x=float(L[0])
y=float(L[1])
z=float(L[2])
f.write("SP 0 0 0\n")
#Eingabe der Punkte
L=Eingabe(["Anzahl der Punkte=", "Anzahl der Linien="])
zeile=[]
p=int(L[0]) # Anzahl der Punkte
l=int(L[1]) # Anzahl der Linien
for i in range(0, p):
txt="Punkt " + str(i) + " X-Koordinate="
zeile.extend([txt])
txt="Punkt " + str(i) + " Y-Koordinate="
zeile.extend([txt])
txt="Punkt " + str(i) + " Z-Koordinate="
zeile.extend([txt])
L=Eingabe(zeile)
zeile=[]
for i in range(0, p):
line="0" + " P " + str(float(L[i*3])-x) + " " + str(float(L[i*3 + 1])-y) + " " + str(float(L[i*3 + 2])-z) + "\n"
f.write(line)
# Eingabe der Linien
for i in range(0, l):
txt="Linie " + str(i) + " Startpunkt="
zeile.extend([txt])
txt="Linie " + str(i) + " Endpunkt="
zeile.extend([txt])
L=Eingabe(zeile)
for i in range(0, l):
line="0" + " L " + L[i*2] + " " + L[i*2 + 1] + "\n"
f.write(line)
f.close()
def Neue_Simulation(modus):
global LBL, pstart, M, R, pz, lz, oz, zeit, lfz, t_alt, P, Kalibrierung, G
global R, V, O, F, ROTATION, BM, BP, BV, S, NAME, LINIE, SKALIERUNG, ZOOM
global UPS, D, ZK, Z, ROJEKTION, Anzahl_Objekte, BV_Schritt
if modus == "ändern": sim="Simulator/" + Datei_wählen("_sim")
elif modus == "neu":
L=[]
L=Eingabe(["Name der Simulation="])
sim='Simulator/' + L[0] + '_sim.txt'
if (os.path.isfile(sim)) and Bestätigung("Datei existiert bereits, soll sie überschrieben werden ?") == "n": return(1)
#Prüfe Existenz von Verzeichnis
if (os.path.isdir('Simulator') == False): os.mkdir('Simulator')
# Setzen der Defaultwerte bzw Laden der aktuellen Werte
if modus == "ändern": Data.Laden(sim)
else:
ZK=1
Z=1
BP.append(Data(0,"", 0, 0, 0))
BM.append(Data(0, "", 1, 0, 0))
BM.append(Data(0, "", 0, 1, 0))
BM.append(Data(0, "", 0, 0, 1))
BV.append(Data(0, "", 0, 0, 0))
BV_Schritt=1
ZOOM=1
UPS.append(Data(0))
ROTATION.append(Data(0, "", 0, 0, 0))
# Spezifiziere Beobachtungssystem
fs=open(sim,"w+")
objnr=0
L=["Beobachterposition X/Y/Z="+str(BP[0].x) + "/" + str(BP[0].y) + "/" +str(BP[0].z)]
L.extend(["Beobachterkoordinatensystem X-Achse: X/Y/Z="+str(BM[0].x) + "/" +str(BM[0].y) + "/" + str(BM[0].z)])
L.extend(["Beobachtekoordinatensystemx Y-Achse: X/Y/Z="+str(BM[1].x) + "/" + str(BM[1].y) + "/" + str(BM[1].z)])
L.extend(["Beobachterkoordinatensystem Z-Achse: X(Y(Z="+str(BM[2].x) + "/" + str(BM[2].y) + "/" + str(BM[2].z)])
L.extend(["Beobachtergeschwindigkeit in X/Y/Z="+str(BV[0].x) + "/" + str(BV[0].y) + "/" + str(BV[0].z)])
L.extend(["Simulierte Zeit zwischen den Simulationsschritten in Sekunde="+str(Z),"Anzahl der zu berechnenden Zyklen="+str(ZK)])
L.extend(["Zoomfaktor="+str(ZOOM), "Schrittweite der Änderung der Beobachtergeschwindigkeit="+str(BV_Schritt)])
L=Eingabe(L)
zeile=L[0].split("/")
line=str(objnr) + " BP " + zeile[0] + " " + zeile[1] + " " + zeile[2] + "\n"
fs.write(line)
zeile=L[1].split("/")
line=str(objnr) + " BM " + zeile[0] + " " + zeile[1] + " " + zeile[2] + "\n"
fs.write(line)
zeile=L[2].split("/")
line=str(objnr) + " BM " + zeile[0] + " " + zeile[1] + " " + zeile[2] + "\n"
fs.write(line)
zeile=L[3].split("/")
line=str(objnr) + " BM " + zeile[0] + " " + zeile[1] + " " + zeile[2] + "\n"
fs.write(line)
zeile=L[4].split("/")
line=str(objnr) + " BV " + zeile[0] + " " + zeile[1] + " " + zeile[2] + "\n"
fs.write(line)
line="0 Z " + L[5] + "\n"
fs.write(line)
line="0 ZK " + L[6] + "\n"
fs.write(line)
line="0 ZOOM " + L[7] + "\n"
fs.write(line)
line="0 BVS " + L[8] + "\n"
fs.write(line)
L=["Zentralprojektion", "Parallelprojektion", "Projektion_auf_Kugel"]
antwort=Auswahl(L)
line="0 PROJEKTION " + antwort + "\n"
fs.write(line)
#Lese Objekte aus Katalog ein, und individualisiere sie
while True :
obj=Datei_wählen("_obj")
obj='Simulator/' + obj
F.append(Data(0, "black"))
O.append(Data(0, "", 0, 0, 0))
V.append(Data(0, "", 0, 0, 0))
ROTATION.append(Data(0,"", 0, 0, 0))
M.append(Data(1))
SKALIERUNG.append(Data(0, "", 1, 1, 1))
NAME.append(Data(0, "?"))
UPS.append(Data(0))
L=["Farbe (Englisch klar oder #...... als RGB Wert="+F[objnr].txt]
L.extend(["Skalierung Achsen X/Y/Z=" +str(SKALIERUNG[objnr].x) + "/" + str(SKALIERUNG[objnr].y) + "/" + str(SKALIERUNG[objnr].z)])
L.extend(["Startposition des Objekts X/Y/Z="+str(O[objnr].x) + "/" + str(O[objnr].y) + "/" + str(O[objnr].z)])
L.extend(["Geschwindigkeit in X/Y/Z="+str(V[objnr].x) +"/" + str(V[objnr].y) + "/" + str(V[objnr].z)])
L.extend(["Masse in Kg="+str(M[objnr].objnr),"Objektbezeichnung="+NAME[objnr].txt,"Umdrehungen pro Sekunde (- für Linksdehung)="+str(UPS[objnr].objnr)])
L.extend(["Rotationsvektor X/Y/Z="+str(ROTATION[objnr].x) + "/" +str(ROTATION[objnr].y) + "/" + str(ROTATION[objnr].z)])
L=Eingabe(L)
sk=L[1].split("/")
line=str(objnr) + " SKALIERUNG " + sk[0] + " " + sk[1] + " " + sk[2] + "\n"
fs.write(line)
line=str(objnr) + " F " + L[0] + "\n"
fs.write(line)
zeile=L[3].split("/")
line=str(objnr) + " V " + zeile[0] + " " + zeile[1] + " " + zeile[2] + "\n"
fs.write(line)
zeile=L[2].split("/")
line=str(objnr) + " O " + zeile[0] + " " + zeile[1] + " " + zeile[2] + "\n"
fs.write(line)
line=str(objnr) + " M " + L[4] + "\n"
fs.write(line)
line=str(objnr) + " NAME " + L[5] + "\n"
fs.write(line)
line=str(objnr) + " UPS " + L[6] + "\n"
fs.write(line)
# Normierung des Rotationsvektors
zeile=L[7].split("/")
n1=float(zeile[0])
n2=float(zeile[1])
n3=float(zeile[2])
betrag=(n1**2 + n2**2 + n3**2)**0.5
if betrag > 0:
n1 = n1 / betrag
n2 = n2 / betrag
n3 = n3 / betrag
line=str(objnr) + " ROTATION " + str(n1) + " " + str(n2) + " " + str(n3) + "\n"
fs.write(line)
# schreibe adaptierte Objektdaten in Simulationsdatei
fo=open(obj,"r")
for l in fo:
zeile=l.split()
if (zeile[0] == "P"):
x=str(float(sk[0]) * float(zeile[1]))
y=str(float(sk[1]) * float(zeile[2]))
z=str(float(sk[2]) * float(zeile[3]))
line=str(objnr) + " P " + x + " " + y + " " + z + "\n"
fs.write(line)
else:
line=str(objnr) + " " + l
fs.write(line)
fo.close()
objnr +=1
if modus == "ändern" and Anzahl_Objekte > objnr:
txt="Alte Simulation enthält mehr Objekte, trotzdem beenden ?"
else:
txt="Ist die Simulation nun fertig ?"
if Bestätigung(txt) == "j":
fs.write(line)
fs.close()
break
def Simulation():
global Kollisionswarnung, counter, Zyklen, ZK, log
# Wähle Datei aus und öffne sie
fn="Simulator/" + Datei_wählen("_sim")
Data.Laden(fn)
# Lege Logfile an
logfile=fn.replace("_sim","_log",1)
log=open(logfile,"w+")
# Schleife durch alle Zyklen
Kollisionswarnung=1
counter=Zyklen=0
Data.Kalibrierung()
Data.Zyklus_berechnen()
Zyklen += 1
while Zyklen < ZK:
#Data.Zyklus_berechnen()
w.after(100, Data.Zyklus_berechnen())
Zyklen += 1
if Zyklen >= ZK:
Zeit,Einheit=Zeit_anpassen(lfz)
line="Laufzeit: " + '{:.2f}'.format(Zeit) + Einheit + "\nWeitere(n) " + str(ZK) + " Zyklen starten ?"
if Bestätigung(line) == "j": Zyklen=0
log.close()
os.chdir("/Users/Lenovo/Google Drive/Dokumente/Software/Python")
master = Tk()
master.geometry('1200x800')
master.title("Mein Simulator")
w = Canvas(master,width=1200,height=800)
w.pack
LabelZyklen = Label(master=master, bg='#FFCFC9', text='0')
LabelZyklen.place(x=1000, y=0, width=200, height=27)
button = Button(master, text='Plot löschen', width=20, command=löschen)
button.place(x=800, y=0, width=100, height=25)
button = Button(master, text='Neu laden', width=20, command=neu_laden)
button.place(x=900, y=0, width=100, height=25)
button = Button(master, text='Hoch drehen\nX-Achse Links', width=100, command=lambda: Beobachter_drehen("x","links"))
button.place(x=800, y=25, width=100, height=50)
button = Button(master, text='Runter drehen\nX-Achse Rechts', width=100, command=lambda: Beobachter_drehen("x","rechts"))
button.place(x=900, y=25, width=100, height=50)
button = Button(master, text='Links drehen\nY-Achse Links', width=100, command=lambda: Beobachter_drehen("y","links"))
button.place(x=800, y=75, width=100, height=50)
button = Button(master, text='Rechts drehen\nY-Achse Rechts', width=100, command=lambda: Beobachter_drehen("y","rechts"))
button.place(x=900, y=75, width=100, height=50)
button = Button(master, text='Links drehen\nZ-Achse Links', width=100, command=lambda: Beobachter_drehen("z","links"))
button.place(x=800, y=125, width=100, height=50)
button = Button(master, text='Ansicht drehen\nZ-Achse Rechts', width=100, command=lambda: Beobachter_drehen("z","rechts"))
button.place(x=900, y=125, width=100, height=50)
button = Button(master, text='Rechts bewegen\nX-Achse', width=100, command=lambda: Beobachter_bewegen("x","+"))
button.place(x=900, y=175, width=100, height=50)
button = Button(master, text='Links bewegen\nX-Achse', width=100, command=lambda: Beobachter_bewegen("x","-"))
button.place(x=800, y=175, width=100, height=50)
button = Button(master, text='Hoch bewegen\nY-Achse', width=100, command=lambda: Beobachter_bewegen("y","+"))
button.place(x=900, y=225, width=100, height=50)
button = Button(master, text='Runter bewegen\nY-Achse', width=100, command=lambda: Beobachter_bewegen("y","-"))
button.place(x=800, y=225, width=100, height=50)
button = Button(master, text='Vorwärts bewegen\nZ-Achse', width=100, command=lambda: Beobachter_bewegen("z","+"))
button.place(x=900, y=275, width=100, height=50)
button = Button(master, text='Rückwärts bewegen\nZ-Achse', width=100, command=lambda: Beobachter_bewegen("z","-"))
button.place(x=800, y=275, width=100, height=50)
Label_BP = Label(master=master, text='Beobachterposition')
Label_BP.place(x=800, y=325, width=200, height=25)
Label_BV = Label(master=master, text='Beobachtergeschwindigkeit')
Label_BV.place(x=800, y=350, width=200, height=25)
Label_BM = Label(master=master, text='Blickrichtung')
Label_BM.place(x=800, y=375, width=200, height=50)
menu = Menu(master)
master.config(menu=menu)
filemenu = Menu(menu)
menu.add_cascade(label="Simulation", menu=filemenu)
filemenu.add_command(label="Starte existierende Simulation", command=Simulation)
filemenu.add_command(label="Existierende Simulation verändern", command= lambda: Neue_Simulation("ändern"))
filemenu.add_command(label="Definiere neue Simulation", command= lambda: Neue_Simulation("neu"))
filemenu.add_command(label="Definiere neue Objektmaster", command=Neue_Objekte)
filemenu.add_separator()
filemenu.add_command(label="Exit", command=master.quit)
master.mainloop()