Benutzer-Werkzeuge

Webseiten-Werkzeuge


ss16:physiksimulation_doc_python

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen gezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen Revision Vorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
ss16:physiksimulation_doc_python [2016/08/13 16:23]
markumnus Main.py beschrieben
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==== ====Programmstruktur====
 {{ :​ss16:​physiksimulation_struktur2107.png?​nolink |}} {{ :​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==== ====Main.py====
Zeile 26: Zeile 175:
     self.w.show()     self.w.show()
 </​code>​ </​code>​
-... welches wiederum Buttons hat, die z.B. beim Klicken auf "​OK"​ ein Objekt erstellen und es zunächst per [[|Interface]] im [[|Universe]] speichern:+... 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> <code Python>
 def output0(self):​ def output0(self):​
Zeile 35: Zeile 184:
     interface.add (obj)     interface.add (obj)
 </​code>​ </​code>​
 +Auf die gleiche Weise werden die Berechnungen und die Visualisierung gestartet.
  
 Der Einstiegspunkt ist dann einfach folgender: Der Einstiegspunkt ist dann einfach folgender:
ss16/physiksimulation_doc_python.1471098216.txt.gz · Zuletzt geändert: 2016/08/13 16:23 von markumnus