Benutzer-Werkzeuge

Webseiten-Werkzeuge


Seitenleiste

ws1718:programmcode
import pygame
from random import uniform
import numpy as np
from numpy import sign
from scipy.spatial import cKDTree
 
def board(screen,xsc,sizey,bloblist,struc): 												#Funktion die das Board in jeder Iteration neu zeichnet
	i=0
	k=0
	pinc=0
	while (i<struc):
		pygame.draw.line(screen,0,((xsc/2)+(xsc*i), sizey),(((xsc/2)+(xsc)*i), (sizey-50)))	#Zeichnet die Linien der Faecher
 
		while (k<=i):																		#Zeichnet einen Punkt an jeder Koordinate in der "bloblist"-Liste
			pygame.draw.line(screen,0,bloblist[pinc],bloblist[pinc])
			pinc=pinc+1
			k=k+2
		i=i+1    
		k=i*(-1)
 
 
 
def main(sizex, sizey, struc, radi, nball, mode,filos):											#Hauptfunktion
 
	pygame.init()																			#erzeugung der pygame instanz
	screen = pygame.display.set_mode((int(sizex), int(sizey)))								#Setzt die Fenstergroesse anhand der Uebergeben Groessen fest
	pygame.display.set_caption("Galton")													#Name des Fensters
	screen.fill((255,255,255))																#hintergurndfarbe
 
	pygame.draw.line(screen,0,(50.0,50),(50,150))											#Massstab um groessen zu Vergleichen
	pygame.draw.circle(screen,0,(int(50),int(50.0)),5,0)
 
	#-------------------VARIABLEN--------------------------------------------------------------------------------------------------------------------------------------------------
 
	i=0
	k=0
	j=0
 
	by=0.0				#Y-Impuls der Kugel
	bx=0.0				#X-Impuls der Kugel
 
	t=0.0				#Zeitparameter
	s=9000000.0			#Maxmimale Zeit, Abruchkriterium
 
	colisionY=0.0		#Y-Koordinate des Abstands zwichen 2 Punkten
	colisionX=0.0		#X-Koordinate des Abstands zwichen 2 Punkten
 
	bloblist= []		#Liste aller Pins (Enthaelt je ein Orts-Tupel)
	loballs=[]			#Liste aller Kugel und ihrer Eigenschaften
	poballs=[]			#Liste aller Kugelpositionen (Enthaelt je ein Orts-Tupel)
 
	pinc=0				#Zaehler der die Pins zaehlt, wird zur erzeugung der Pinstruktur benoetigt
 
	bacou=0				#Beschreibt die Farbe der Kugel
 
 
	grav=0.00981		#Gravitationskontante, Bestimmt die zuname der Geschwindigkeit in Y-richtung
 
	#radi=5				#Radius der Kugel, Bestimmt auch Kollisionsradius
 
	zahlen=''			#String in dem jedesmal wenn eine Kugel in ein Fach faellt die Nummer des Fachs geschrieben wird
	a=0					#Anzahl der Kugel in einem Fach
	w=(struc*(-0.5))	#das am weitesten Linke Fach
	dati=""				#String der in die Datei geschrieben wird
 
	coliimpx=0.0		#Variablen die zur Berechnung der dezentralen Kollision verwendet werden
	coliimpy=0.0
	coliswapx=0.0
	coliswapy=0.0
	impimpx=0.0
	impimpy=0.0
 
	xsc=(sizex/(struc))		#Struktur Einteilung in X-Richtung
	ysc=(sizey/(struc+1))	#Struktur Einteilung in Y-Richtung
 
	#-------------------ERZEUGUNG------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 
	if mode >1: # Verhindert Modi groesser 1
		mode=1
 
 
	while i<nball:																							# Erzeugung der Kugeln
		loballs.append([(sizex/2)+(np.random.rand()-0.5)*5, (np.random.rand()-0.5)*5 + (sizey/2 *mode), (bx+(np.random.rand()-0.5)*0.02+(np.random.rand()-0.5)*0.5*mode), (by+(np.random.rand()-0.5)*0.02*mode), bacou]) # (X-Position,Y-Position,X-Impuls,Y-Impuls,Farbe)
		loballs[i][4]=((np.random.randint(0,255)),(np.random.randint(0,255)),(np.random.randint(0,255))) 	#Erzeugung der Farbe durch RNG
		i=i+1	
	i=0
 
	if mode==0: 																							#Modus Kontrolle (0= Board-Mode, 0!= Testbench)
		while (i<struc):																					#Erzeugung des Boards
			pygame.draw.line(screen,0,((xsc/2)+(xsc*i), sizey),(((xsc/2)+(xsc)*i), (sizey-50)))				#Zeichnen der Linien der Faecher
 
			while (k<=i):																					#Erzeugung der Pins
				bloblist.append(((((sizex/2)+(xsc/2)*(k))), ((ysc)*i)+50))
				pygame.draw.line(screen,0,bloblist[pinc],bloblist[pinc])
 
				pinc=pinc+1
				k=k+2
			i=i+1    
			k=i*(-1)
		i=0
 
		tree = cKDTree(bloblist,leafsize=1)																	#Erzeugung des Pin-Tree in dem alle Orte der Pins gespeichert werden
 
 
#-------------------Bewegung und Kollision---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
	while t!=s:																								#Grosse Schleife, bricht ab sobald Zeitparameter t den Abruchparameter s erreicht
		if t!=s:
 
			t=t+1																							#Iteriert den Zeitparameter
			screen.fill((255,255,255))																		#setzt das Fenster auf Weiss zurueck
 
 
			poballs=[]																						#Leert die Liste
			for ball in loballs:																			#Fuegt die aktuellen Positionen aller Kugeln hinzu
				poballs.append((ball[0],ball[1]))
 
			tree2 = cKDTree(poballs, leafsize=1)															#Erzeugt den Kugel-Tree
 
 
			#-------------------Bewegung------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
			for ball in loballs:
 
				if mode==0:																					#Modus Kontrolle (0= Board-Mode, 0!= Testbench)
					ball[3]=ball[3]+grav																	#Fuegt der Y-Impulskoordinate die Gravitation hinzu (in Testbench nicht noetig)
				ball[0]=ball[0]+ball[2]																		#Addiert die X-Impulskoordinate auf den X-Ort der Kugel (Bewegung)
				ball[1]=ball[1]+ball[3]																		#Addiert die Y-Impulskoordinate auf den Y-Ort der Kugel (Bewegung)
 
				pygame.draw.circle(screen,ball[4],(int(ball[0]),int(ball[1])),radi,0)						#Zeichnet die Kugel am neuen Ort in ihrer Farbe
				pygame.draw.circle(screen,(0,0,0),(int(ball[0]),int(ball[1])),radi,1)						#Zeichnet schwarzen Rand um die Kugel
 
				#-------------------Kollision-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
				#----------------------Wand---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
				if ball[0]>=(sizex-5):																		#rechtsseitiger Rand
					ball[2]=ball[2]*(-1)
 
				if ball[0]<=5:																				#linksseitiger Rand
					ball[2]=ball[2]*(-1)
 
 
				if mode!=0:																					#Modus Kontrolle (0= Board-Mode, 0!= Testbench)
					if ball[1]>=(sizey-5):																	#unterer Rand (nur in Testbench)
						ball[3]=ball[3]*(-1)
					if ball[1]<=(5):																		#oberer Rand (nur in Testbench)
						ball[3]=ball[3]*(-1)
 
				#----------------------Pin---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------	
				if mode ==0:																				#Modus Kontrolle (0= Board-Mode, 0!= Testbench)
					d,j= tree.query([ball[0],ball[1]])														#dursucht den Pin-Tree nach naechstem Pin
					if d <radi:
 
						colisionY = ball[1]-bloblist[j][1]													#Bestimmung des Abstandsvektors
						colisionX = ball[0]-bloblist[j][0]
 
						ball[3]=0.5*ball[3]*sign(ball[3])*sign(colisionY)									#Reversion des Kugel-Impulses, wenn dieser auf den Pin zeigt
						ball[2]=ball[2]*sign(ball[2])*sign(colisionX)
 
						if abs(ball[3])<grav:																#Verhindert das der Impuls zu klein wird und die Kugel am Pin 'klebt'
							ball[3]=ball[3]+(sign(ball[3])*0.8*grav)
						if abs(ball[2])<0.002:
							ball[2]=ball[2]+((np.random.rand()-0.5)*0.05)
 
				#----------------------Kugel-Kugel---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------	
				h,g= tree2.query(([ball[0],ball[1]]),2)														#durchsucht den Kugel-Tree nach naechste Kugel die nicht sie selbst ist
				if h[1]<(2*radi):
					if g[1]<len(loballs):
						colisionY = ball[1]-loballs[g[1]][1]+0.000001										#Bestimmung des Abstandsvektors der Beiden Kugeln
						colisionX = ball[0]-loballs[g[1]][0]+0.000001										#+0.0000001 damit der Abstand nicht 0 wird [WORKAROUND]
 
						coliimpx = colisionX*ball[2]														#multiplikation mit den Impulskoordinaten der Kugel mit dem Abstandsvektor
						coliimpy = colisionY*ball[3]
						impimpx = ball[2]*loballs[g[1]][2]													#multiplikation der Impulskoordinaten beider Kugeln
						impimpy = ball[3]*loballs[g[1]][3]
 
						if sign(coliimpx)*sign(impimpx) >=0:												#check ob beide Impulse aufeinander zu zeigen
							if sign(coliimpy)*sign(impimpy) >=0:
 
								coliimpx = (((ball[2]-loballs[g[1]][2])*colisionX + (ball[3]-loballs[g[1]][3])*colisionY)*colisionX)/(colisionX**2+colisionY**2)	# dezentrale Kollision 
								coliimpy = (((ball[2]-loballs[g[1]][2])*colisionX + (ball[3]-loballs[g[1]][3])*colisionY)*colisionY)/(colisionX**2+colisionY**2)
 
								loballs[g[1]][2]=loballs[g[1]][2]+0.5*coliimpx 								#Impuls neu zuweisung
								loballs[g[1]][3]=loballs[g[1]][3]+0.5*coliimpy
 
								ball[2]=ball[2]-coliimpx													#Impuls neu zuweisung
								ball[3]=ball[3]-coliimpy
				#----------------------Fach--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
				if mode ==0:																				#Modus Kontrolle (0= Board-Mode, 0!= Testbench)
					if ball[1]>=(sizey-40):																	#Zaehlung der Kugel im Fach
						c=int(ball[0]/(sizex/(struc+1)))-((struc)/2)
						zahlen=zahlen + " " + str(c) + " "
			#----------------------Endkriterien----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
			if mode ==0:																					#Modus Kontrolle (0= Board-Mode, 0!= Testbench)
				loballs = [ ball for ball in loballs if ball[1]<sizey-40]									#Ausschluss aller in Faecher gefallenen Kugeln
 
			if not loballs:																					#Abruch sobald alle Kugel in Faechern sind
				t=s
			if mode ==0:																					#Modus Kontrolle (0= Board-Mode, 0!= Testbench)
				board(screen,xsc,sizey,bloblist,struc)														#neuzeichnen des Bretts
		pygame.display.flip()
	#----------------------Auswertung--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
	if mode ==0:																							#Modus Kontrolle (0= Board-Mode, 0!= Testbench)
		f=open(filos+".txt", "w")
		while w<=(struc/2):																					#Zaehlung der Kugeln in den Faechern und schreiben der AAnzahlen in die Datei
			dt=" "+str(w) + " "
			a=zahlen.count(dt)
			dati= dati + str(w) + "\t" + str(a) +"\t"  + "\n"
			w=w+1
		f.write(dati)
		f.close()
		print "fin"
 
filos="pygg_data3" 																							#Dateiname
 
main(500.0, 500.0, 12.0, 5, 200, 0, filos)
ws1718/programmcode.txt · Zuletzt geändert: 2018/03/26 04:33 von m.hansemann