Gravitationsfeld/-feldlinien, -simulation 2D

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
Olaf
Beiträge: 117
Registriert: 20.04.2006 14:51
Wohnort: 66606 St.Wendel (Niederlinxweiler, Dr.Albert-Schweitzer-Str.9)
Kontaktdaten:

Gravitationsfeld/-feldlinien, -simulation 2D

Beitrag von Olaf »

Mal ne kleine Simulation zur Bewegung eines Körpers im 2dimensionalen Raum, der von 4 Massen (kann im
Quellcode beliebig verändert werden) angezogen wird. In diesem Fall sind die Massen jedoch fest und nicht selbst
beweglich (vgl. Magnetpendel).

Code: Alles auswählen

Enumeration
	#Window
	#ImageGadget
	#XText
	#XSpin
	#YText
	#YSpin
	#Start
	#Pause
	#Stop
	#Erase
	#ActX
	#ActY
	#Kraftfeld
	#Hintergrund
	#HintergrundThread
	#Display
EndEnumeration

Structure df
	fx.d
	fy.d
EndStructure

Structure mass
	x.d
	y.d
	m.d
EndStructure

Global Gravitation_Const.d=1,StdMass.d=1

Global NewList Masses.mass()

m.d=1000000
Dist.d=200

Global w.l,h.l,KoordX.l,KoordY.l

w=600
h=600

KoordX=457
KoordY=254

CreateImage(#Hintergrund,w*2,h)
CreateImage(#HintergrundThread,w*2,h)
CreateImage(#Kraftfeld,w,h)
CreateImage(#Display,w*2,h)

Raster=40
radius=2*Raster/40

First=1

If First<>0
	AddElement(Masses())
	Masses()\x=300+Cos(60*#PI/180)*Dist
	Masses()\y=300+Sin(60*#PI/180)*Dist
	Masses()\m=m
EndIf

Second=1

If Second<>0
	AddElement(Masses())
	Masses()\x=300+Cos(180*#PI/180)*Dist
	Masses()\y=300+Sin(180*#PI/180)*Dist
	Masses()\m=m
EndIf

Third=1

If Third<>0
	AddElement(Masses())
	Masses()\x=300+Cos(300*#PI/180)*Dist
	Masses()\y=300+Sin(300*#PI/180)*Dist
	Masses()\m=m
EndIf

Fourth=1

If Fourth<>0
	AddElement(Masses())
	Masses()\x=300
	Masses()\y=300
	Masses()\m=m
EndIf

Procedure.d Absolute(*Vector.df)
	Distance.d=Sqr(*Vector\fx**Vector\fx+*Vector\fy**Vector\fy)
	ProcedureReturn Distance
EndProcedure

Procedure.l GetColor(Absolute.d)
	;ColorSeed.c=Int(Sqr(Absolute)/680*255)
	ColorSeed=Int(Absolute)
	Color.l=RGB(255-ColorSeed,255-ColorSeed,255)
	ProcedureReturn Color
EndProcedure

Procedure.d GetAngle(Sin.d,Cos.d)
	Angle.d=ATan(Sin/Cos)
	If Sin<0 And Cos<0
		Angle+#PI
	ElseIf Cos<0 And Sin>=0
		Angle+#PI
	ElseIf Sin<0 And Cos>=0
		Angle+2*#PI
	EndIf
	If Angle>2*#PI
		Angle-2*#PI
	EndIf
	ProcedureReturn Angle
EndProcedure

Procedure GetGravitation(x.d,y.d,*Vector.df)
	ResetList(Masses())
	*Vector\fx=0
	*Vector\fy=0
	While NextElement(Masses())
		deltax.d=(x-Masses()\x)
		deltay.d=(y-Masses()\y)
		r.d=Sqr(deltax*deltax+deltay*deltay)
		F.d=-Gravitation_Const*StdMass*Masses()\m/(r*r)
		*Vector\fx+F*deltax/r
		*Vector\fy+F*deltay/r
	Wend
EndProcedure

Procedure DrawTestMass(x,y)
	If x<=w
		Circle(x,y,4,RGB(200,200,200))
		Circle(x,y,3,RGB(000,128,128))
	EndIf
EndProcedure

Procedure Simulation()
	CopyImage(#Hintergrund,#HintergrundThread)
	x.d=KoordX
	y.d=KoordY
	TimeStep=8
	Repeat
		GetGravitation(x,y,Kraft.df)
		ax.d=Kraft\fx/StdMass
		ay.d=Kraft\fy/StdMass
		vx.d=vx+ax*TimeStep/1000
		vy.d=vy+ay*TimeStep/1000
		x   =x +vx*TimeStep/1000
		y   =y +vy*TimeStep/1000
		StartDrawing(ImageOutput(#HintergrundThread))
			;Circle(Int(x)  ,Int(y),1,RGB(000,128,128))
			Circle(Int(x+w),Int(y),1,RGB(000,128,128))
		StopDrawing()
		StartDrawing(ImageOutput(#Display))
			DrawImage(ImageID(#HintergrundThread),0,0)
			DrawTestMass(Int(x)  ,Int(y))
			;DrawTestMass(Int(x+w),Int(y))
		StopDrawing()
		SetGadgetState(#ImageGadget,ImageID(#Display))
		SetGadgetText(#ActX,"Aktuell X: "+Str(x))
		SetGadgetText(#ActY,"Aktuell Y: "+Str(y))
		Delay(TimeStep/2)
	Until x>w Or y>h Or x<0 Or y<0
	DisableGadget(#Start,0)
	DisableGadget(#Pause,1)
	DisableGadget(#Stop ,1)
	DisableGadget(#XSpin,0)
	DisableGadget(#YSpin,0)
	DisableGadget(#Erase,0)
	Repeat
		Delay(10)
	ForEver
EndProcedure

Procedure Erase()
	StartDrawing(ImageOutput(#Display))
		DrawImage(ImageID(#Hintergrund),0,0)
		DrawTestMass(KoordX,KoordY)
	StopDrawing()
	SetGadgetState(#ImageGadget,ImageID(#Display))
	SetGadgetText(#ActX,"Aktuell X: "+Str(KoordX))
	SetGadgetText(#ActY,"Aktuell Y: "+Str(KoordY))
EndProcedure

OpenWindow(#Window,0,0,w*2,h+40,"Gravitationsfeld, -linien und -simulation",#PB_Window_ScreenCentered|#PB_Window_MinimizeGadget)
StartDrawing(ImageOutput(#Kraftfeld))
	For x=0 To w
		For y=0 To h
			GetGravitation(x,y,Vector.df)
			Abs.d=Absolute(Vector)
			Plot(x,y,Int(Abs))
		Next y
	Next x
StopDrawing()
StartDrawing(ImageOutput(#Hintergrund))
	DrawImage(ImageID(#Kraftfeld),0,0)
	For x=0 To w
		For y=0 To h
			If x%Raster=0 And y%Raster=0	And x<w And y<h And x<>0 And y<>0
				GetGravitation(x,y,Vector.df)
				Angle.d=GetAngle(Vector\fy,Vector\fx)
				dx.l=Int(Cos(Angle)*10*Raster/40)
				dy.l=Int(Sin(Angle)*10*Raster/40)
				dA.d=#PI/6+#PI
				dxp1.l=Int(Cos(Angle+dA)*7*Raster/40)
				dyp1.l=Int(Sin(Angle+dA)*7*Raster/40)
				dxp2.l=Int(Cos(Angle-dA)*7*Raster/40)
				dyp2.l=Int(Sin(Angle-dA)*7*Raster/40)
				Circle(x,y,radius,16777215)
				Line(x-dx,y-dy,dx*2,dy*2,16777215)
				Line(x+dx,y+dy,dxp1,dyp1,16777215)
				Line(x+dx,y+dy,dxp2,dyp2,16777215)
				Circle(x+w,y,radius,16777215)
				Line(x-dx+w,y-dy,dx*2,dy*2,16777215)
				Line(x+dx+w,y+dy,dxp1,dyp1,16777215)
				Line(x+dx+w,y+dy,dxp2,dyp2,16777215)
			EndIf
		Next y
	Next x
StopDrawing()
StartDrawing(ImageOutput(#Display))
	DrawImage(ImageID(#Hintergrund),0,0)
	DrawTestMass(KoordX,KoordY)
StopDrawing()
	CreateGadgetList(WindowID(#Window))
		ImageGadget(#ImageGadget,0,0,w*2,h,ImageID(#Display))
		TextGadget(#XText, 10,h+10  ,40,20,"Start-X:")
		StringGadget(#XSpin, 50,h+10-3,60,20,Str(KoordX),#PB_String_Numeric|#PB_Text_Right)
		TextGadget(#YText,120,h+10  ,40,20,"Start-Y:")
		StringGadget(#YSpin,160,h+10-3,60,20,Str(KoordY),#PB_String_Numeric|#PB_Text_Right)
		ButtonGadget(#Start,280,h+10-3,50,20,"Start")
		ButtonGadget(#Pause,340,h+10-3,50,20,"Pause")
			DisableGadget(#Pause,1)
		ButtonGadget(#Stop, 400,h+10-3,50,20,"Stop")
			DisableGadget(#Stop ,1)
		ButtonGadget(#Erase,460,h+10-3,50,20,"Löschen")
			DisableGadget(#Erase,1)
		TextGadget(#ActX,520,h+10,70,20,"Aktuell X: "+Str(KoordX))
		TextGadget(#ActY,600,h+10,70,20,"Aktuell Y: "+Str(KoordY))
Repeat
	event=WaitWindowEvent()
	Select event
		Case #PB_Event_Gadget
			Select EventGadget()
				Case #XSpin
					KoordX=Val(GetGadgetText(#XSpin))
					If KoordX>w
						KoordX=w
						SetGadgetText(#XSpin,Str(KoordX))
					ElseIf KoordX<0
						KoordX=0
						SetGadgetText(#XSpin,Str(KoordX))
					EndIf
					StartDrawing(ImageOutput(#Display))
						DrawImage(ImageID(#Hintergrund),0,0)
						DrawTestMass(KoordX,KoordY)
					StopDrawing()
					SetGadgetState(#ImageGadget,ImageID(#Display))
				Case #YSpin
					KoordY=Val(GetGadgetText(#YSpin))
					If KoordY>h
						KoordY=h
						SetGadgetText(#YSpin,Str(KoordY))
					ElseIf KoordY<0
						KoordY=0
						SetGadgetText(#YSpin,Str(KoordY))
					EndIf
					StartDrawing(ImageOutput(#Display))
						DrawImage(ImageID(#Hintergrund),0,0)
						DrawTestMass(KoordX,KoordY)
					StopDrawing()
					SetGadgetState(#ImageGadget,ImageID(#Display))
				Case #Start
					If IsThread(Simulation)
						KillThread(Simulation)
					EndIf
					Simulation=CreateThread(@Simulation(),0)
					DisableGadget(#Start,1)
					DisableGadget(#Pause,0)
					DisableGadget(#Stop ,0)
					DisableGadget(#XSpin,1)
					DisableGadget(#YSpin,1)
					DisableGadget(#Erase,1)
				Case #Pause
					If IsThread(Simulation)
						If ThreadPaused=0
							ThreadPaused=1
							PauseThread(Simulation)
						ElseIf ThreadPaused=1
							ThreadPaused=0
							ResumeThread(Simulation)
						EndIf
					EndIf
				Case #Stop
					If IsThread(Simulation)
						KillThread(Simulation)
					EndIf
					DisableGadget(#Start,0)
					DisableGadget(#Pause,1)
					DisableGadget(#Stop ,1)
					DisableGadget(#XSpin,0)
					DisableGadget(#YSpin,0)
					DisableGadget(#Erase,0)
				Case #Erase
					DisableGadget(#Erase,1)
					Erase()
			EndSelect
	EndSelect
Until event=#PB_Event_CloseWindow
PB 4.xx (Windows & Linux & Mac OS X)
Treffen sich 2 Kurven in der Unendlichkeit. Sagt die eine zur anderen: "Hau ab aus meinem Definitionsbereich oder ich leite dich ab!"
Darauf die andere: "Mach nur! Ich bin die e-Funktion." :lol:
Benutzeravatar
Macros
Beiträge: 1365
Registriert: 23.12.2005 15:00
Wohnort: Olching(bei FFB)
Kontaktdaten:

Beitrag von Macros »

Hübsches Programm :allright:

2 meiner Meinung nach ganz hübsche Bahnen:
600/388
600/378

und die Längste, die ich gefunden habe:
600/376

dann gibt es da noch 391/391

wer findet ne längere :lol:
Bild
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

[offtopic]
Mit EnableExplicit läuft der Code nicht :(
Warum deklariert den keiner auch die lokalen Variablen,
Code, Tipps und Tricks sollten vorbildlich sein!

Nur mal nebenbei bemerkt.
[/offtopic]

Hoffentlich mache ich mich jetzt nicht schon wieder unbeliebt :mrgreen:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
THEEX
Beiträge: 804
Registriert: 07.09.2004 03:13

Beitrag von THEEX »

Hmmm, nette Idee, aber müßte der Körper nicht irgendwo an einem Magneten hängen bleiben, anstatt irgendwo dann aus dem Bildschirm zu fliegen?
Benutzeravatar
Olaf
Beiträge: 117
Registriert: 20.04.2006 14:51
Wohnort: 66606 St.Wendel (Niederlinxweiler, Dr.Albert-Schweitzer-Str.9)
Kontaktdaten:

Beitrag von Olaf »

@CSprengel: Nee...es soll ja garkein Magnetpendel sein. Das hab ich ja nur so nebenbei erwähnt wegen der festen Massen.
Es soll lediglich die Gravitationskräfte simulieren. Aber 'n Magnetpendel könnte ich auch mal programmieren.
PB 4.xx (Windows & Linux & Mac OS X)
Treffen sich 2 Kurven in der Unendlichkeit. Sagt die eine zur anderen: "Hau ab aus meinem Definitionsbereich oder ich leite dich ab!"
Darauf die andere: "Mach nur! Ich bin die e-Funktion." :lol:
Benutzeravatar
Kukulkan
Beiträge: 1066
Registriert: 09.09.2004 07:07
Wohnort: Süddeutschland
Kontaktdaten:

Beitrag von Kukulkan »

Hallo,

Ich finde das faszinierend. :allright:

Nur mal so ein Gedanke: Könnte man das nicht auch für die Kryptografie verwenden? Ich meine, man könnte die Position (XA, YA, XB, YB) und Stärke (NA, NB) von zwei Gravitationsfeldern definieren, die Start-Position (XP, YP) und Masse (MP) eines Punktes und dann anhand dessen auf die Position nach zB X Schritten zählen. Die Abweichung in einem der Faktoren sollte das Ergebnis doch (zum Teil) unvorhersehbar verändern, oder? Also man nehme XA,YA,XB,YB,NA,NB,XP,YP, MP und X. Das Ergebnis ist dann XP und YP nach der Zeit X. Als Schlüssel können nun zB die Positionen der Massen funktionieren, oder?

Volker
Benutzeravatar
Olaf
Beiträge: 117
Registriert: 20.04.2006 14:51
Wohnort: 66606 St.Wendel (Niederlinxweiler, Dr.Albert-Schweitzer-Str.9)
Kontaktdaten:

Beitrag von Olaf »

@Volker Schmid:
Ja, an sowas hab ich auch schon gedacht. Müsste funktionieren. Kannst ja mal rumprobieren. :wink:
PB 4.xx (Windows & Linux & Mac OS X)
Treffen sich 2 Kurven in der Unendlichkeit. Sagt die eine zur anderen: "Hau ab aus meinem Definitionsbereich oder ich leite dich ab!"
Darauf die andere: "Mach nur! Ich bin die e-Funktion." :lol:
Benutzeravatar
bluejoke
Beiträge: 1244
Registriert: 08.09.2004 16:33
Kontaktdaten:

Beitrag von bluejoke »

Hallo!

Da ich über Verschlüsselungstechnik eine Arbeit schreiben soll interessiert mich das genauer: Wollt ihr da eine Symmetrische oder Asymmetrische Verschlüsselung probieren?

Simon
Ich bin Ausländer - fast überall
Windows XP Pro SP2 - PB 4.00
Benutzeravatar
Tafkadasom2k5
Beiträge: 1578
Registriert: 13.08.2005 14:31
Kontaktdaten:

Beitrag von Tafkadasom2k5 »

Wenn ich das richtig verstehe, ist sie dann doch symmetrisch, weil man (sofern ich das verstehe) die gleichen Parameter, sowie den richtigen Algorhytmus für diese Schwerkraft-Simulation braucht, um den Klartext zu erzeugen, oder?

Gr33tz
Tafkadasom2k5
OpenNetworkConnection() hat geschrieben:Versucht eine Verbindung mit dem angegebenen Server aufzubauen. 'ServerName$' kann eine IP-Adresse oder ein voller Name sein (z.B.: "127.0.0.1" oder "ftp.home.net").
php-freak hat geschrieben:Ich hab die IP von google auch ned rausgefunden!
Benutzeravatar
Olaf
Beiträge: 117
Registriert: 20.04.2006 14:51
Wohnort: 66606 St.Wendel (Niederlinxweiler, Dr.Albert-Schweitzer-Str.9)
Kontaktdaten:

Beitrag von Olaf »

@Tafkadasom2k5: richtig verstanden :lol:
Ja, in dem Fall wäre es ne symmetrische Verschlüsselung.
@bluejoke: Falls es dich interessiert, hab ich noch ne asymmetrische Verschlüsselung entwickelt:
Über ne Maske werden die Bits in nem Byte vertauscht.
Hierbei ist der Entschlüsselungskey aber 'n anderer als der Verschlüsselungskey.
Wenns dich interessiert, kann ich dir den Code auch mal geben bzw. mal posten. :wink:
PB 4.xx (Windows & Linux & Mac OS X)
Treffen sich 2 Kurven in der Unendlichkeit. Sagt die eine zur anderen: "Hau ab aus meinem Definitionsbereich oder ich leite dich ab!"
Darauf die andere: "Mach nur! Ich bin die e-Funktion." :lol:
Antworten