Benutzer-Werkzeuge

Webseiten-Werkzeuge


Seitenleiste

ss16:physiksimulation_doc_python

Hauptseite des Projekts

Physiksimulation/Dokumentation/Komponenten/

Python-Teil

Programmstruktur

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.

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

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.

#######################################
# 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__()

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.

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

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

self.addSonne.clicked.connect(self.Add_Sonne) # 'addSonne' ist der Name des in der Window.ui-Datei deklarierten Buttons

die Methode Add_Sonne aufgerufen. Diese erstellt ein PopupWindow…

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()

… welches wiederum Buttons hat, die z.B. beim Klicken auf „OK“ ein Objekt erstellen und es zunächst per Interface im Universe speichern:

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)

Auf die gleiche Weise werden die Berechnungen und die Visualisierung gestartet.

Der Einstiegspunkt ist dann einfach folgender:

if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    window = MyApp()
    window.move(QtCore.QPoint(850, 300))
    window.show()
    sys.exit(app.exec_())
ss16/physiksimulation_doc_python.txt · Zuletzt geändert: 2016/08/14 22:37 von markumnus