Benutzer-Werkzeuge

Webseiten-Werkzeuge


ss16:physiksimulation_doc_python

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen gezeigt.

Link zu dieser Vergleichsansicht

Nächste Überarbeitung
Vorhergehende Überarbeitung
ss16:physiksimulation_doc_python [2016/08/13 15:46]
markumnus angelegt
ss16:physiksimulation_doc_python [2016/08/14 22:37] (aktuell)
markumnus
Zeile 3: Zeile 3:
 </​a></​center></​html>​ </​a></​center></​html>​
  
-<- [[ss16:​Physiksimulation_doc_components|zurück zur Liste der Komponenten]]+**[[ss16:​Physiksimulation|Physiksimulation]]/​[[ss16:​Physiksimulation_Doc_Main|Dokumentation]]/​[[ss16:​Physiksimulation_doc_components|Komponenten]]/** 
 +=====Python-Teil=====
  
-=====Physiksimulation ​| Python-Teil=====+ 
 +====Programmstruktur==== 
 +{{ :​ss16:​physiksimulation_struktur2107.png?​nolink ​|}} 
 + 
 + 
 +====Parser.py==== 
 +In der Ergebnis-Textdatei sind einzelne Zeitschritte mit **//|//** getrennt, Objekte mit **//;//** und die Koordinaten der Objekte mit **//,//**. Die //​parse()//​-Funktion macht aus einem String nach diesem Muster eine Liste aus Tupeln mit den Positionsdaten. 
 +<​code ​Python
 +def parse (string): 
 +    """​ 
 +    Nimmt einen String mit Object-Positionsdaten entgegen und 
 +    gibt eine Liste aus Tupeln mit Positionsdaten zurueck. 
 +    Beispiel: 
 +    "​0.0037,​ 0.0024, -0.0001;​-0.315,​ -0.9603, -0.0001;​-0.3129,​ -0.9592, -0.0002;​|"​ -> [(0.0037, 0.0024, -0.0001), (-0.315, -0.9603, -0.0001), (-0.3129, -0.9592, -0.0002)] 
 +    """​ 
 +    result ​[] 
 +  
 +    # aufteilen 
 +    objects = string.split(";"​) 
 + 
 +    # bereinigen 
 +    for o in objects: 
 +        if o == "":​ 
 +            objects.remove(o) 
 +  
 +    # Koordinaten extrahieren 
 +    for o in objects: 
 + coords = o.split(","​) 
 +  
 + # Whitespace entfernen 
 + for i, c in enumerate (coords): 
 +     coords[i] = c.strip() 
 +  
 + # in Floats umwandeln 
 +     try: 
 + coords = map (float, coords) 
 +     except ValueError:​ 
 + print "​Konnte",​ coords, "nicht umwandeln."​ 
 +  
 +     result.append (tuple(coords)) 
 +  
 +    return result 
 +</​code>​ 
 + 
 + 
 +====Reader.py==== 
 +In der Datei Reader.py wird die Klasse Reader definiert. Wir haben uns hier für eine Klasse entschieden (anstatt nur einer Funktion wie beim Parser), da wir die //​%%__getitem__()%%//​-Funktion nutzen wollten, um die Ergebnis-Datei wie eine Liste indizierbar zu machen. Mit reader[time_step] kann man bequem auf die Positionsdaten des jeweiligen Zeitschritts zugreifen. 
 +<code Python>​ 
 +#######################################​ 
 +# IMPORTE 
 +#######################################​ 
 +import Parser 
 + 
 +class Reader: 
 + 
 +    time_steps = [] 
 + 
 +    def __init__ (self, filename):​ 
 +        # Deklarationen 
 +        self.FILENAME = filename 
 + 
 +        # File lesen 
 +        with open (self.FILENAME) as f: 
 +            file_cont = f.read() 
 + 
 +        # Zeitschritte voneinander trennen | 
 +        self.time_steps = file_cont.split('​|'​) 
 +         
 +        # letztes, leeres Element entfernen 
 +        self.time_steps.pop() 
 + 
 + 
 +    def __getitem__ (self, key): 
 +        """​ 
 +        Indiziert einen Zeitschritt und gibt die Koordinaten der Objects zu diesem Zeitschritt zurueck. 
 +        """​ 
 +        return Parser.parse(self.time_steps[key]) 
 +     
 +     
 +    def __len__ (self): 
 +        """​ 
 +        Gibt Anzahl der verfuegbaren Zeitschritte zurueck. 
 +        """​ 
 +        return len (self.time_steps) 
 +     
 +    def __str__ (self): 
 +        s = "​Reader auf \""​ + self.FILENAME + "​\"​ mit " + str(len(self)) + " Zeitschritten."​ 
 +        return s 
 + 
 +    def __repr__(self):​ 
 +        return self.__str__() 
 + 
 +</​code>​ 
 + 
 + 
 +====Visualizer.py==== 
 +Diese Datei deklariert die Klasse //​Visualizer//​. Im Konstruktor nimmt sie eine Liste mit Objekten entgegen, die visualisiert werden sollen. Außerdem wird die //scene// für Visual initialisiert.\\ 
 +Mit der Methode //run()// wird die Animation gestartet. Die benötigten Positionsdaten werden mithilfe des Readers ausgelesen. 
 +<code Python>​ 
 +from visual import * 
 +from Reader import * 
 +from PyCInterface import PyCObject 
 + 
 +class Visualizer:​ 
 +    def __init__ (self, list_of_objects,​ source = "​results.txt"​):​ 
 + """​ 
 + Initialisiert den Visualizer mit verschiedenen Konstanten und Grundfunktionen,​ 
 + sowie mit einer Liste an Objekten, die gezeichnet werden sollen 
 + """​ 
 + self.PROGRAM_NAME = "​Gravitationssimulation"​ 
 + self.SPEED = 100 
 + self.reader = Reader (source) 
 + self.time = 0 
 + self.PyCObjects = [] # Objekte mit vom User gegebenen Daten wie Name, Farbe, Groesse, etc. 
 + self.Objects = [] # Objekte von Visual, die die Anzeige beeinflussen 
 + self.renew_objects (list_of_objects) 
 +  
 + # Initialisierung von Visual 
 + scene = display (title = self.PROGRAM_NAME,​\ 
 + x=0, y=0, width=1920,​height=1080,​\ 
 + range=10,​ background=color.black,​ center = (0,0,0)) 
 +  
 +        def renew_objects (self, list_of_objects):​ 
 +     """​ 
 +     Setzt die Objects komplett neu. 
 +     """​ 
 +     self.PyCObjects = list_of_objects #​ Objekte mit vom User gegebenen Daten wie Name, Farbe, Groesse, etc. 
 +     self.Objects = [] # Objekte von Visual, die die Anzeige beeinflussen 
 + 
 +     # lese Daten aus 
 +     for i, o in enumerate(self.PyCObjects):​ 
 +     try: 
 +      pos_o = self.reader[0][i] 
 +     size_o = o.size 
 +     color_o = o.color 
 +             self.Objects.append(sphere(pos=pos_o,​ radius = size_o, color = color_o, make_trail = true)) 
 + except IndexError:​ 
 +     print "Mehr Objekte uebergeben als berechnet wurden:",​ i 
 + 
 + def run (self): 
 +     """​ 
 +     Laeuft einmal durch alle Daten und zeigt diese an. 
 +     """​ 
 +     # Loop bis Fileende: 
 +     # update die Positionen 
 +     while self.time < len(self.reader):​ 
 +         rate (self.SPEED) 
 +     for i, o in enumerate (self.Objects):​ 
 + o.pos = self.reader[self.time][i] #​ Object des aktuellen Zeitschrittes 
 +     self.time += 1 
 +</​code>​ 
 + 
 + 
 +====Main.py==== 
 +In dieser Datei werden mehrere Klassen definiert, darunter die MyApp-Klasse,​ die das Programm darstellt und einige PopupWindow-Klassen,​ die die Funktionen des Fensters steuern.\\ 
 +Bei einem Klick auf einen Button wird mit der Codezeile 
 +<code Python>​ 
 +self.addSonne.clicked.connect(self.Add_Sonne) # '​addSonne'​ ist der Name des in der Window.ui-Datei deklarierten Buttons 
 +</​code>​ 
 +die Methode Add_Sonne aufgerufen. 
 +Diese erstellt ein PopupWindow... 
 +<code Python>​ 
 +def Add_Sonne(self):​ 
 +    print "​Creating a new Sun..."​ 
 +    self.w = PopupWindow0() 
 +    self.w.setWindowTitle("​Sonne erstellen..."​) 
 +    self.w.setGeometry(QtCore.QRect(500,​ 200, 360, 300)) 
 +    self.w.show() 
 +</​code>​ 
 +... welches wiederum Buttons hat, die z.B. beim Klicken auf "​OK"​ ein Objekt erstellen und es zunächst per [[ss16:​Physiksimulation_Doc_cpp#​Interface.cpp|Interface]] im [[ss16:​Physiksimulation_Doc_cpp#​Universe.cpp|Universe]] speichern:​ 
 +<code Python>​ 
 +def output0(self):​ 
 +    obj = PyCObject() 
 +    obj.x = float(PositionEditx0.text()) # uebernehme 
 +    obj.y = float(PositionEdity0.text()) # Positionsdaten 
 +    obj.z = float(PositionEditz0.text()) # vom Benutzer 
 +    interface.add (obj) 
 +</​code>​ 
 +Auf die gleiche Weise werden die Berechnungen und die Visualisierung gestartet. 
 + 
 +Der Einstiegspunkt ist dann einfach folgender:​ 
 +<code Python>​ 
 +if __name__ ​== "​__main__":​ 
 +    app QtGui.QApplication(sys.argv) 
 +    window ​MyApp() 
 +    window.move(QtCore.QPoint(850,​ 300)) 
 +    window.show() 
 +    sys.exit(app.exec_()) 
 +</​code>​
ss16/physiksimulation_doc_python.1471095965.txt.gz · Zuletzt geändert: 2016/08/13 15:46 von markumnus