Teilchensimulation

Übersicht BlitzBasic Codearchiv

Neue Antwort erstellen

 

codegeneral

Betreff: Teilchensimulation

BeitragSo, Feb 22, 2009 23:21
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo

Ich bin neu hier im Forum und programmiere erst seit kurzem. Im Chemieunterricht haben wir neulich Ionen und Kristallgitter durchgenommen. Dann habe ich hier im Forum ein wenig gestöbert und bin auf Gravitationssimulationen gestossen. Und weil mich so Spielereien fasziniert und ich etwas Erfahrung im Programmieren sammeln will habe ich das Prinzip auf Ionen übertragen.

Es gelten folgende einfache Regeln.
- Gleiche geladene Teilchen stossen sich ab.
- Unterschiedliche geladene Teilchen ziehen sich an.
- Auf alle Teilchen wirkt die Gravitation
- Auf nahe Teilchen wirkt ein Druck der sie auseinander treibt

Code: [AUSKLAPPEN]

Const scrnX = 600
Const scrnY = 400
Const Size = 8
Const Teilchenanzahl = 16  ;Anzahl Positiver und Negativer eilchen
Const calcsPROframe = 3
Const Teilchenbremse# = 0.999

Graphics scrnX ,scrnY ,32,2
SetBuffer BackBuffer()
SeedRnd MilliSecs()

Type LT ;(LT.. Ladungsträger)
   Field x#
   Field y#
   Field xdir#
   Field ydir#
   Field l       
End Type

Global LT.LT

For i = 1 To Teilchenanzahl
   LT.LT = New LT
   LT\x = Rnd(1,scrnX)
   LT\y = Rnd(1,scrnY)
   LT\l = -1
Next

For i = 1 To Teilchenanzahl
   LT.LT = New LT
   LT\x = Rnd(1,scrnX)
   LT\y = Rnd(1,scrnY)
   LT\l = 1
Next

While Not KeyHit(1)
   Cls
   timer = MilliSecs()
   
   For qw = 1 To calcsPROframe
      Anziehung()
      bewegung()
   Next   
   
   visualisieren()
   
   
   Text 2,2,MilliSecs()-timer
   
   Flip
Wend

Function Anziehung()
   For a.LT=Each LT
      For b.LT=Each LT
         If a=b Then Exit
         
         xa#=a\x-b\x
         ya#=a\y-b\y
         ab#=1.0/(ya*ya+xa*xa)
         
         b\xdir=b\xdir+xa*(Abs(a\l)*ab/33) ;==================================== Gravitation
         b\ydir=b\ydir+ya*(Abs(a\l)*ab/33)
         a\xdir=a\xdir-xa*(Abs(b\l)*ab/33)
         a\ydir=a\ydir-ya*(Abs(b\l)*ab/33)      ;=> Anziehung
         
         If a\l + b\l <> 0 ;unterschiedliche Ladung ============================ Coulombkraft
            b\xdir=b\xdir-xa*(Abs(a\l)*ab)
            b\ydir=b\ydir-ya*(Abs(a\l)*ab)
            a\xdir=a\xdir+xa*(Abs(b\l)*ab)
            a\ydir=a\ydir+ya*(Abs(b\l)*ab)       ;=> Abstossung
         Else
            b\xdir=b\xdir+xa*(Abs(a\l)*ab)
            b\ydir=b\ydir+ya*(Abs(a\l)*ab)
            a\xdir=a\xdir-xa*(Abs(b\l)*ab)
            a\ydir=a\ydir-ya*(Abs(b\l)*ab)       ;=> Anziehung
         End If
         
         If ab*1000000 > 1400 Then   ;========================================== Druck
            b\xdir=b\xdir-xa*(Abs(a\l)*ab*1.5)
            b\ydir=b\ydir-ya*(Abs(a\l)*ab*1.5)
            a\xdir=a\xdir+xa*(Abs(b\l)*ab*1.5)
            a\ydir=a\ydir+ya*(Abs(b\l)*ab*1.5)    ;=> Abstossung
         End If
      Next
   Next
End Function

Function bewegung()
   For Lt.Lt = Each LT
      LT\x = LT\x + LT\xdir
      LT\y = LT\y + LT\ydir
      
      If LT\x < 0 Then LT\xdir = LT\xdir - 2*LT\xdir
      If LT\x > scrnX Then LT\xdir = LT\xdir - 2*LT\xdir
      If LT\y < 0 Then LT\ydir = LT\ydir - 2*LT\ydir
      If LT\y > scrnY Then LT\ydir = LT\ydir - 2*LT\ydir
      
      ;Abschwächung der Bewegung
      LT\xdir = LT\xdir*Teilchenbremse
      LT\ydir = LT\ydir*Teilchenbremse
   Next
End Function

Function visualisieren()
   For Lt.Lt = Each LT
      If LT\l = 1 Then Color 255,0,0
      If LT\l = -1 Then Color 0,0,255
      Oval(LT\x,Lt\y,size,size,1)   
   Next
End Function

End


Falls es zu langsam geht einfach die Konstante calcsPROframe vergrössern.

Sehr interessant wäre eine 3D umsetzung vielleich auch mit unterschiedlich grossen Teilchen aus denen dann andere Gitterformen entstehen würden.

tedy

BeitragSo, Feb 22, 2009 23:39
Antworten mit Zitat
Benutzer-Profile anzeigen
Habs mir mal angeschaut :O
Gefällt mir Very Happy

Ist nett azusehen wie sich die Teilchen ausrichten und ein rechteck bilden
01010100 01100101 01000100 01111001 00100000 00111010 01000100

FireballFlame

BeitragMo, Feb 23, 2009 0:00
Antworten mit Zitat
Benutzer-Profile anzeigen
Nicht ganz - bei Teilchenanzahl = 3 kommt früher oder später immer ein schönes regelmäßiges Sechseck heraus und bei größeren Mengen wie z.B. 250 drücken die äußeren Teilchen dermaßen nach innen, dass eher sowas wie ne Kugel draus wird Very Happy
https://www.blitzforum.de/upload/file.php?id=4824
https://www.blitzforum.de/upload/file.php?id=4825
PC: Intel Core i7 @ 4x2.93GHz | 6 GB RAM | Nvidia GeForce GT 440 | Desktop 2x1280x1024px | Windows 7 Professional 64bit
Laptop: Intel Core i7 @ 4x2.00GHz | 8 GB RAM | Nvidia GeForce GT 540M | Desktop 1366x768px | Windows 7 Home Premium 64bit
 

codegeneral

BeitragMo, Feb 23, 2009 20:08
Antworten mit Zitat
Benutzer-Profile anzeigen
@FireballFlame

Liegt an der Gravitation das bei grossen Teilchenanzahlen eine Kugel entsteht. Ohne bilden sich andere Strukturen.

https://www.blitzforum.de/upload/file.php?id=4834

Silver_Knee

BeitragMi, Feb 25, 2009 22:43
Antworten mit Zitat
Benutzer-Profile anzeigen
hmm wer an die reibung n paar 9er dranhängt bekommt wie ne art waserstoff xD

aMul

Sieger des Minimalist Compo 01/13

BeitragMi, Feb 25, 2009 23:28
Antworten mit Zitat
Benutzer-Profile anzeigen
Das ist wirklich ein toller Code.
Ich als Geometrie-Narr kann mich mit sowas ewig beschäftigen.

Hier zwei interessante Sachen die mir untergekommen sind:

https://www.blitzforum.de/upload/file.php?id=4843
https://www.blitzforum.de/upload/file.php?id=4844
(seht ihr auch ne Taube? Mr. Green )
Panic Pong - ultimate action mashup of Pong and Breakout <= aktives Spiele-Projekt, Downloads mit vielen bunten Farben!
advASCIIdraw - the advanced ASCII art program <= aktives nicht-Spiele-Projekt, must-have für ASCII/roguelike/dungeon-crawler fans!
Alter BB-Kram: ThroughTheAsteroidBelt - mit Quelltext! | RGB-Palette in 32²-Textur / Farbige Beleuchtung mit Dot3 | Stereoskopie in Blitz3D | Teleport-Animation Screensaver
 

codegeneral

BeitragDo, Feb 26, 2009 21:40
Antworten mit Zitat
Benutzer-Profile anzeigen
@aMul: schön dass es dir gefällt und ja, dass zweite Bild hat was von einem Vogel Very Happy
 

Roma3ht

BeitragDo, Feb 26, 2009 21:41
Antworten mit Zitat
Benutzer-Profile anzeigen
lol echt lustig das erste bild sieht aus wie ne Glübirne und das 2. wie ein vogel..Echt geil der code.
 

codegeneral

Betreff: 3D

BeitragDo, Feb 26, 2009 22:55
Antworten mit Zitat
Benutzer-Profile anzeigen
Hab noch per Zufall einen grossen Ring erhalten.

https://www.blitzforum.de/upload/file.php?id=4859

Nun zur eigentlichen Neuerung. Ich hab versucht das ganze in 3D umzusetzen.

Code: [AUSKLAPPEN]

Const scrnX = 500
Const scrnY = 500
Const raum = 500
Const Size = 18
Const Teilchenanzahl = 100  ;Anzahl Positiver und Negativer eilchen
Const calcsPROframe = 3
Const Teilchenbremse# = 0.9
SeedRnd MilliSecs()

Graphics3D scrnX ,scrnY ,32,2

cam=CreateCamera()
sun=CreateLight(1)
PositionEntity cam,0,0,-raum-1000
CameraRange cam,1,raum*10

Type LT ;(LT.. Ladungsträger)
   Field x#
   Field y#
   Field z#
   Field xdir#
   Field ydir#
   Field zdir#
   Field entity
   Field l       
End Type

Global LT.LT

For i = 1 To Teilchenanzahl
   LT.LT = New LT
   LT\x = Rnd(-raum,raum)
   LT\y = Rnd(-raum,raum)
   LT\z = Rnd(-raum,raum)
   LT\entity = CreateSphere(8)
   PositionEntity LT\entity,LT\x,LT\y,LT\z
   ScaleEntity LT\entity,size,size,size
   EntityColor LT\entity,255,0,0
   LT\l = -50
Next

For i = 1 To Teilchenanzahl
   LT.LT = New LT
   LT\x = Rnd(-raum,raum)
   LT\y = Rnd(-raum,raum)
   LT\z = Rnd(-raum,raum)
   LT\entity = CreateSphere(8)
   PositionEntity LT\entity,LT\x,LT\y,LT\z
   ScaleEntity LT\entity,size,size,size
   EntityColor LT\entity,0,0,255
   LT\l = 50
Next

While Not KeyHit(1)
      timer = MilliSecs()
   
   For qw = 1 To calcsPROframe
      Anziehung()
      bewegung()
   Next   
   
   If KeyDown(205)=1 Then TurnEntity cam,0,-1,0
   If KeyDown(203)=1 Then TurnEntity cam,0,1,0
   If KeyDown(208)=1 Then MoveEntity cam,0,0,-5
   If KeyDown(200)=1 Then MoveEntity cam,0,0,5
 
   RenderWorld
   UpdateWorld
   Text 2,2,MilliSecs()-timer 
   Flip
Wend

Function Anziehung()
   For a.LT=Each LT
      For b.LT=Each LT
         If a=b Then Exit
         
         xa#=a\x-b\x
         ya#=a\y-b\y
       za#=a\z-b\z
         ab#=1.0/((ya*ya+xa*xa+za*za))
         
         If a\l + b\l <> 0 ;unterschiedliche Ladung ============================ Coulombkraft
            b\xdir=b\xdir-xa*(Abs(a\l)*ab)
            b\ydir=b\ydir-ya*(Abs(a\l)*ab)
         b\zdir=b\zdir-za*(Abs(a\l)*ab)
         
            a\xdir=a\xdir+xa*(Abs(b\l)*ab)
            a\ydir=a\ydir+ya*(Abs(b\l)*ab)
            a\zdir=a\zdir+za*(Abs(b\l)*ab)        ;=> Abstossung
         
         Else
            b\xdir=b\xdir+xa*(Abs(a\l)*ab)
            b\ydir=b\ydir+ya*(Abs(a\l)*ab)
         b\zdir=b\zdir+za*(Abs(a\l)*ab)
         
            a\xdir=a\xdir-xa*(Abs(b\l)*ab)
            a\ydir=a\ydir-ya*(Abs(b\l)*ab)
            a\zdir=a\zdir-za*(Abs(b\l)*ab)       ;=> Anziehung
         End If
         
         If ab*1000000 > 1400 Then   ;========================================== Druck
            b\xdir=b\xdir-xa*(Abs(a\l)*ab*1.5)
            b\ydir=b\ydir-ya*(Abs(a\l)*ab*1.5)
         b\zdir=b\zdir-za*(Abs(a\l)*ab*1.5)
         
            a\xdir=a\xdir+xa*(Abs(b\l)*ab*1.5)
            a\ydir=a\ydir+ya*(Abs(b\l)*ab*1.5)
            a\zdir=a\zdir+za*(Abs(b\l)*ab*1.5)   ;=> Abstossung
         End If
      Next
   Next
End Function

Function bewegung()
   For Lt.Lt = Each LT
      LT\x = LT\x + LT\xdir
      LT\y = LT\y + LT\ydir
      LT\z = LT\z + LT\zdir
     
      If LT\x < -raum Then LT\xdir = LT\xdir - 2*LT\xdir
      If LT\x >  raum Then LT\xdir = LT\xdir - 2*LT\xdir

      If LT\y < -raum Then LT\ydir = LT\ydir - 2*LT\ydir
      If LT\y >  raum Then LT\ydir = LT\ydir - 2*LT\ydir

      If LT\z < 0  Then LT\zdir = LT\zdir - 2*LT\zdir
      If LT\z > 0  Then LT\zdir = LT\zdir - 2*LT\zdir

      ;Abschwächung der Bewegung
      LT\xdir = LT\xdir*Teilchenbremse
      LT\ydir = LT\ydir*Teilchenbremse
      LT\zdir = LT\ydir*Teilchenbremse

     PositionEntity LT\entity,LT\x,LT\y,LT\z
   Next
End Function

End


Kamerasteuerung mit Pfeiltasten.

Es bilden sich bei mir immer nur lange Schlangen aber nie Blöcke. Weiss jemand woran das liegt?

aMul

Sieger des Minimalist Compo 01/13

BeitragDo, Feb 26, 2009 23:14
Antworten mit Zitat
Benutzer-Profile anzeigen
Hab es mir aus Zeitmangel nur kurz angeschaut, aber ich glaube es liegt daran, dass die Abstoßung zwischen gleichen Teilchen einfach zu groß ist, sodass diese sich nicht gerne im Viereck anordnen.
Sobald ich etwas Zeit finde werde ich nochmal drüber schauen, ich habe schon eine Vermutung wie man das beheben kann.

EDIT:

Ok, ich habe was gefunden.
Ich hoffe es stört dich nicht, dass ich den halben Code umgeschrieben habe. Wink

Zum einen habe ich deine Funktion "Anziehen" etwas optimiert(und an meinen Stil angepasst):
Code: [AUSKLAPPEN]
Function Anziehung()
   Local a.LT, b.LT, xa#, ya#, za#, ab#
   For a.LT = Each LT
      b.LT = After a
      Repeat
         If b = Null
            Exit
         End If
         
         xa = a\x - b\x
         ya = a\y - b\y
         za = a\z - b\z
         ab = AbstandFaktor / (ya * ya + xa * xa + za * za)
         
         If a\l + b\l <> 0 ;unterschiedliche Ladung ============================ Coulombkraft
            b\xdir = b\xdir - xa * Abs(a\l) * ab
            b\ydir = b\ydir - ya * Abs(a\l) * ab
            b\zdir = b\zdir - za * Abs(a\l) * ab
            
            a\xdir = a\xdir + xa * Abs(b\l) * ab
            a\ydir = a\ydir + ya * Abs(b\l) * ab
            a\zdir = a\zdir + za * Abs(b\l) * ab        ; = > Abstossung
            
         Else
            b\xdir = b\xdir + xa * Abs(a\l) * ab
            b\ydir = b\ydir + ya * Abs(a\l) * ab
            b\zdir = b\zdir + za * Abs(a\l) * ab
            
            a\xdir = a\xdir - xa * Abs(b\l) * ab
            a\ydir = a\ydir - ya * Abs(b\l) * ab
            a\zdir = a\zdir - za * Abs(b\l) * ab       ; = > Anziehung
         End If
         
         If ab * 1000000 > 1400 Then   ;========================================== Druck
            b\xdir = b\xdir - xa * Abs(a\l) * ab * DruckFaktor
            b\ydir = b\ydir - ya * Abs(a\l) * ab * DruckFaktor
            b\zdir = b\zdir - za * Abs(a\l) * ab * DruckFktor
            
            a\xdir = a\xdir + xa * Abs(b\l) * ab * DruckFaktor
            a\ydir = a\ydir + ya * Abs(b\l) * ab * DruckFaktor
            a\zdir = a\zdir + za * Abs(b\l) * ab * DruckFaktor  ;=> Abstossung
         End If
         b = After b
      Forever
   Next
End Function

Ich habe außerdem zwei neue Konstanten angeführt, AbstandFaktor und DruckFaktor, um diese beiden Größen einfacher variieren zu können.

Und genau das habe ich dann auch gemacht. Die schönsten Ergebnisse bekomme ich bisher mit:
Code: [AUSKLAPPEN]
Const AbstandFaktor# = 5
Const DruckFaktor# = 1.5

So formen sich zumindest halbwegs dreidimensionale Objekte aller Art.

Achja, die Hauptschleife habe ich mir übrigens auch noch umgeschrieben um bessere Kontrolle zu haben.
Code: [AUSKLAPPEN]
Local calc = 1, timer, qw
MoveMouse scrnX / 2, scrnY / 2

While Not KeyHit(1)
   timer = MilliSecs()
   
   If calc
      For qw = 1 To calcsPROframe
         Anziehung()
         bewegung()
      Next 
   End If
   
   If KeyHit(57)
      calc = 1 - calc
   End If
   
   MoveEntity cam, (KeyDown(32) - KeyDown(30)) * 10, 0, (KeyDown(17) - KeyDown(31)) * 10
   TurnEntity cam, MouseYSpeed(), -MouseXSpeed(), 0
   
   MoveMouse scrnX / 2, scrnY / 2
   
   RenderWorld
   UpdateWorld
   Text 2,2,MilliSecs()-timer
   Flip 0
   Delay 10 - MilliSecs() + timer
Wend

Bewegen geht hier mit WASD und Umsehen mit Maus.
Außerdem kann man mit der Leertaste die Teilchen einfrieren. Zumindest mir fällt es dann wesentlich leichter die räumliche Anordnung zu erkennen.
Weiterhin habe ich noch das Delay eingebaut, damit mein Rechner bei gefrorenen Teilchen nicht unnötig arbeitet(auf 100 FPS begrenzt).

So, dass war es erstmal von mir.
Ich hoffe ich konnte behilflich sein. Wink


EDIT2:
Wollte nur noch kurz festhalten, dass die mit meinen Modifikationen entstehenden Gebilde mit ihrer 2D-Pseudo-3D-Art mich an Proteine erinnern, die ja im Prinzip auch nur 1D sind sich aber aufgrund ihrer Zusammensetzung zu 3D-Gebilden verformen.
 

codegeneral

BeitragSa, Feb 28, 2009 12:52
Antworten mit Zitat
Benutzer-Profile anzeigen
Sehr schön, jetzt bilden ich richtige Strukturen. Interessant ist, dass es am Anfang eine 3D Netzt bildet, später aber meistens flache 2D Strukturen entstehen.

aMul

Sieger des Minimalist Compo 01/13

BeitragSa, Feb 28, 2009 13:07
Antworten mit Zitat
Benutzer-Profile anzeigen
Ja, das ist mir auch aufgefallen.
Interessant finde ich, dass sich meistens eine große Fläche bildet, die sich dann irgendwann wieder in viele kleine Sachen(zB. Ringe) auflöst.

Ich werde noch ein bisschen experimentieren, vielleicht kann ich es ja dazu bringen wirklich 3D-Objekte zu bilden.
Panic Pong - ultimate action mashup of Pong and Breakout <= aktives Spiele-Projekt, Downloads mit vielen bunten Farben!
advASCIIdraw - the advanced ASCII art program <= aktives nicht-Spiele-Projekt, must-have für ASCII/roguelike/dungeon-crawler fans!
Alter BB-Kram: ThroughTheAsteroidBelt - mit Quelltext! | RGB-Palette in 32²-Textur / Farbige Beleuchtung mit Dot3 | Stereoskopie in Blitz3D | Teleport-Animation Screensaver

Fobsi

BeitragSa, Feb 28, 2009 13:12
Antworten mit Zitat
Benutzer-Profile anzeigen
nach 10min sind die kleinen kreise alle angehalten ^^

lg Fobsi

Neue Antwort erstellen


Übersicht BlitzBasic Codearchiv

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group