Planetorium

Miscellaneous Forums/Blitz Showcase/Planetorium

Hi,

here is a small new BlitzMax-program.
It simulates gravity between many "planets"!
Because the code is very messy, I don't explain the details in this text, but if you have questions I'd like to answer them.

Now information you gonna need.At the top of the code are a few variables which you can change in the code:

- anzahl = change "anzahl" to set the number of planets

- ausgleich = "ausgleich" is a factor which influences the speed of the planets

-weite = "weite" sets how big the area is in which the planets can move

-zufweite = sets how big the area is in which the planets are created

-gu = sets how big the planets can be when they are created

These factors are in the program code as it is now very high. You can chose them however you like. Please try out!

The control also is quite easy:

- SPACE: Shows the direction of every planet
- "g": Shows the biggest gravity-connections
- "a": Zoom out
- "s": Zoom in
- "Cursor-Keys: Move camera"

I hope you'll enjoy the program:

Graphics 800,600
Global ausgleich:Double 
Global weite:Double 
Global gu:Double 

Global ABSP:Int 
Global GRP:Int 
Global reg:Double 

absp = 2
grp = 2

anzahl = 50
ausgleich= 40000000
weite = 10000000000
zufweite = 500000
gu = 500000000

reg = 1


Global planets:Double[anzahl]
Global planetg:Double[anzahl]
Global planetx:Double[anzahl]
Global planety:Double[anzahl]
Global planetxs:Double[anzahl]
Global planetys:Double[anzahl]
Global greatest:Double[anzahl]
Global greatestp:Double[anzahl]
Global color:Double[anzahl]

Global zoom:Double
Global gesamtgroesse:Double = .1
Global verhx:Double

Global verhy:Double


Global xp:Double 
Global yp:Double 

xp = weite
yp = weite
zoom = (1/(weite/200))


Global abstandx:Double
Global abstandy:Double
Global abstand:Double
Global richtungx:Double
Global richtungy:Double
Global ausgleich2:Double
Global aenderungsr:Double



For x = 0 To (anzahl-1)



planetx[x] =Rnd (-zufweite,zufweite)
planety[x] = Rnd(-zufweite,zufweite)

planetg[x] = Rand(1,gu)

Next



Repeat


For xx = 0 To (anzahl-1)


SetColor 150+color[xx],150+color[xx],100
DrawOval (planetx[xx]+xp)*zoom,(planety[xx]+yp)*zoom,(planetg[xx]^0.5)*zoom+1,(planetg[xx]^0.5)*zoom+1


planetx[xx] = planetx[xx] + planetxs[xx]
planety[xx] = planety[xx] + planetys[xx]

color [xx] = 0


Next

gesamtgroesse = 0.1


For xx3 = 0 To (anzahl-1)

greatest[xx3] = 0
For yy3 = 0 To (anzahl-1)


abstandx = (Abs((planetx[xx3]+(planetg[xx3]^0.5/2))-(planetx[yy3]+planetg[yy3]^0.5/2)))^2
abstandy = (Abs((planety[xx3]+(planetg[xx3]^0.5/2))-(planety[yy3]+planetg[yy3]^0.5/2)))^2

abstandx2 = (Abs(planetx[xx3]-planetx[yy3]))
abstandy2 = (Abs(planety[xx3]-planety[yy3]))
abstand = ((abstandx)+(abstandy))^0.5



If abstand < ((planetg[xx3]^0.5/2)+(planetg[yy3]^0.5/2)) And xx3 <>yy3  Then


If planetg[xx3] >= planetg[yy3] Then
planetx[xx3] = planetx[xx3]
planety[xx3] = planety[xx3]
Else
planetx[xx3] = planetx[yy3]
planety[xx3] = planety[yy3]
End If

planetg[xx3] = planetg[xx3]+planetg[yy3]
planetg[yy3] = Rnd (1,gu*reg)


planetxs[xx3] = (planetxs[xx3]+((planetg[yy3]/planetg[xx3])*planetxs[yy3]))/(1+(planetg[yy3]/planetg[xx3]))
planetys[xx3] = (planetys[xx3]+((planetg[yy3]/planetg[xx3])*planetys[yy3]))/(1+(planetg[yy3]/planetg[xx3]))



planetxs[yy3] = 0
planetys[yy3] = 0





planetx[yy3] = Rnd (-zufweite,zufweite)
planety[yy3] = Rnd (-zufweite,zufweite)


End If


If xx3<>yy3 And abstandy2 <> 0 And abstandx2 <> 0 Then


End If


If xx3<>yy3 Then
ausgleich2= (100/abstand)
Else
ausgleich2 = .01
End If
If xx3 <> yy3 Then
aenderungsr = ( (planetg[yy3]/planetg[xx3])^grp*ausgleich*(1/abstand^absp))

Else
aenderungsr = 0
End If

richtungx = Sin((abstandx^0.5)/(abstandy^0.5))
richtungy = Cos((abstandy^0.5)/(abstandx^0.5))
richtungx = 1
richtungy = 1




If (planetx[xx3]+planetg[xx3]^0.5/2) < (planetx[yy3]+planetg[yy3]^0.5/2) And xx3<>yy3  Then
planetxs[xx3] = (planetxs[xx3] + (aenderungsr*richtungx)  )
Else
planetxs[xx3] = (planetxs[xx3] - (aenderungsr*richtungx))
End If

If (planety[xx3]+planetg[xx3]^0.5/2) < (planety[yy3]+planetg[yy3]^0.5/2) Then
planetys[xx3] = (planetys[xx3] + (aenderungsr*richtungy))
Else
planetys[xx3] = (planetys[xx3] -  (aenderungsr*richtungy))
End If

If aenderungsr > greatest[xx3] Then
greatest[xx3] = aenderungsr
greatestp[xx3] = yy3
color[yy3] = color [yy3] + (100/anzahl)
EndIf


If KeyDown (key_space) Then

SetColor 255,0,0


verhx = (planetxs[xx3]/planetys[xx3])
verhy =(planetys[xx3]/planetxs[xx3])

DrawLine (planetx[xx3]+xp)*zoom,(planety[xx3]+yp)*zoom,(planetx[xx3]+planetxs[xx3]+xp)*zoom,(planety[xx3]+planetys[xx3]+yp)*zoom
End If

gesamtgroesse = gesamtgroesse + planetg[yy3]



If planetx[xx3] > weite Then
planetxs[xx3] = -1
planetx[xx3] = weite 
End If 

If planetx[xx3] < -weite Then
planetxs[xx3] = 1
planetx[xx3] = -weite 

End If 

If planety[xx3] > weite Then
planetys[xx3] = -1
planety[xx3] = weite 

End If 

If planety[xx3] < -weite Then
planetys[xx3] = 1
planety[xx3] = -weite 

End If 



Next

Next



If KeyDown (key_g) Then

For xx4 = 0 To (anzahl-1)
For yy4 = 0 To (anzahl-1)

SetColor 0,255,0

DrawLine (planetx[xx4]+(planetg[xx4]^0.5/2)+xp)*zoom,(planety[xx4]+(planetg[xx4]^0.5/2)+yp)*zoom,(planetx[greatestp[xx4]]+(planetg[greatestp[xx4]]^0.5/2)+xp)*zoom,(planety[greatestp[xx4]]+(planetg[greatestp[xx4]]^0.5/2)+yp)*zoom

Next
Next

End If


SetColor 255,0,0
DrawLine (xp-weite)*zoom,(yp-weite)*zoom,(weite+xp)*zoom,(yp-weite)*zoom
DrawLine (xp+weite)*zoom,(yp-weite)*zoom,(weite+xp)*zoom,(yp+weite)*zoom
DrawLine (xp+weite)*zoom,(yp+weite)*zoom,(xp-weite)*zoom,(yp+weite)*zoom
DrawLine (xp-weite)*zoom,(yp+weite)*zoom,(xp-weite)*zoom,(yp-weite)*zoom

Flip
Cls


If KeyDown (Key_up) Then
yp = yp + (5*1/zoom)
End If
If KeyDown (Key_down) Then
yp = yp - (5*1/zoom)
End If
If KeyDown (Key_right) Then
xp = xp - (5*1/zoom)
End If
If KeyDown (Key_left) Then
xp = xp + (5*1/zoom)
End If

If KeyDown(key_a) Then
zoom = zoom*.99
xp = xp + (4*1/zoom)
yp = yp + (3*1/zoom)

End If
If KeyDown(key_s) Then
zoom = zoom*1.01
xp = xp - (4*1/zoom)
yp = yp - (3*1/zoom)

End If

DrawRect 400,296,1,9
DrawRect 396,300,9,1

Until KeyHit (key_escape)
End 


PS: With this setting you have to zoom in a lot at the beginning!!

Feedback is welcome,
Lukas

I liked it. :)

Hey Lukas that's pretty great! I've always liked gravity simulation planet stuff!!

Thank you guys,

if you have ideas how to improve it and it is not too difficult ;-), tell it to me!

Lukas

Here is another version with the controls at the top of the screen. It think this will be easier to control!

Graphics 800,600
Global ausgleich:Double 
Global weite:Double 
Global gu:Double 

Global ABSP:Int 
Global GRP:Int 
Global reg:Double 

absp = 2
grp = 2

anzahl = 50
ausgleich= 40000000
weite = 10000000000
zufweite = 500000
gu = 500000000

reg = 1


Global planets:Double[anzahl]
Global planetg:Double[anzahl]
Global planetx:Double[anzahl]
Global planety:Double[anzahl]
Global planetxs:Double[anzahl]
Global planetys:Double[anzahl]
Global greatest:Double[anzahl]
Global greatestp:Double[anzahl]
Global color:Double[anzahl]

Global zoom:Double
Global gesamtgroesse:Double = .1
Global verhx:Double

Global verhy:Double


Global xp:Double 
Global yp:Double 

xp = weite
yp = weite
zoom = (1/(weite/200))


Global abstandx:Double
Global abstandy:Double
Global abstand:Double
Global richtungx:Double
Global richtungy:Double
Global ausgleich2:Double
Global aenderungsr:Double



For x = 0 To (anzahl-1)



planetx[x] =Rnd (-zufweite,zufweite)
planety[x] = Rnd(-zufweite,zufweite)

planetg[x] = Rand(1,gu)

Next



Repeat


For xx = 0 To (anzahl-1)


SetColor 150+color[xx],150+color[xx],100
DrawOval (planetx[xx]+xp)*zoom,(planety[xx]+yp)*zoom,(planetg[xx]^0.5)*zoom+1,(planetg[xx]^0.5)*zoom+1


planetx[xx] = planetx[xx] + planetxs[xx]
planety[xx] = planety[xx] + planetys[xx]

color [xx] = 0


Next

gesamtgroesse = 0.1


For xx3 = 0 To (anzahl-1)

greatest[xx3] = 0
For yy3 = 0 To (anzahl-1)


abstandx = (Abs((planetx[xx3]+(planetg[xx3]^0.5/2))-(planetx[yy3]+planetg[yy3]^0.5/2)))^2
abstandy = (Abs((planety[xx3]+(planetg[xx3]^0.5/2))-(planety[yy3]+planetg[yy3]^0.5/2)))^2

abstandx2 = (Abs(planetx[xx3]-planetx[yy3]))
abstandy2 = (Abs(planety[xx3]-planety[yy3]))
abstand = ((abstandx)+(abstandy))^0.5



If abstand < ((planetg[xx3]^0.5/2)+(planetg[yy3]^0.5/2)) And xx3 <>yy3  Then


If planetg[xx3] >= planetg[yy3] Then
planetx[xx3] = planetx[xx3]
planety[xx3] = planety[xx3]
Else
planetx[xx3] = planetx[yy3]
planety[xx3] = planety[yy3]
End If

planetg[xx3] = planetg[xx3]+planetg[yy3]
planetg[yy3] = Rnd (1,gu*reg)


planetxs[xx3] = (planetxs[xx3]+((planetg[yy3]/planetg[xx3])*planetxs[yy3]))/(1+(planetg[yy3]/planetg[xx3]))
planetys[xx3] = (planetys[xx3]+((planetg[yy3]/planetg[xx3])*planetys[yy3]))/(1+(planetg[yy3]/planetg[xx3]))



planetxs[yy3] = 0
planetys[yy3] = 0





planetx[yy3] = Rnd (-zufweite,zufweite)
planety[yy3] = Rnd (-zufweite,zufweite)


End If


If xx3<>yy3 And abstandy2 <> 0 And abstandx2 <> 0 Then


End If


If xx3<>yy3 Then
ausgleich2= (100/abstand)
Else
ausgleich2 = .01
End If
If xx3 <> yy3 Then
aenderungsr = ( (planetg[yy3]/planetg[xx3])^grp*ausgleich*(1/abstand^absp))

Else
aenderungsr = 0
End If

richtungx = Sin((abstandx^0.5)/(abstandy^0.5))
richtungy = Cos((abstandy^0.5)/(abstandx^0.5))
richtungx = 1
richtungy = 1




If (planetx[xx3]+planetg[xx3]^0.5/2) < (planetx[yy3]+planetg[yy3]^0.5/2) And xx3<>yy3  Then
planetxs[xx3] = (planetxs[xx3] + (aenderungsr*richtungx)  )
Else
planetxs[xx3] = (planetxs[xx3] - (aenderungsr*richtungx))
End If

If (planety[xx3]+planetg[xx3]^0.5/2) < (planety[yy3]+planetg[yy3]^0.5/2) Then
planetys[xx3] = (planetys[xx3] + (aenderungsr*richtungy))
Else
planetys[xx3] = (planetys[xx3] -  (aenderungsr*richtungy))
End If

If aenderungsr > greatest[xx3] Then
greatest[xx3] = aenderungsr
greatestp[xx3] = yy3
color[yy3] = color [yy3] + (100/anzahl)
EndIf


If KeyDown (key_space) Then

SetColor 255,0,0


verhx = (planetxs[xx3]/planetys[xx3])
verhy =(planetys[xx3]/planetxs[xx3])

DrawLine (planetx[xx3]+xp)*zoom,(planety[xx3]+yp)*zoom,(planetx[xx3]+planetxs[xx3]+xp)*zoom,(planety[xx3]+planetys[xx3]+yp)*zoom
End If

gesamtgroesse = gesamtgroesse + planetg[yy3]



If planetx[xx3] > weite Then
planetxs[xx3] = -1
planetx[xx3] = weite 
End If 

If planetx[xx3] < -weite Then
planetxs[xx3] = 1
planetx[xx3] = -weite 

End If 

If planety[xx3] > weite Then
planetys[xx3] = -1
planety[xx3] = weite 

End If 

If planety[xx3] < -weite Then
planetys[xx3] = 1
planety[xx3] = -weite 

End If 



Next

Next



If KeyDown (key_g) Then

For xx4 = 0 To (anzahl-1)
For yy4 = 0 To (anzahl-1)

SetColor 0,255,0

DrawLine (planetx[xx4]+(planetg[xx4]^0.5/2)+xp)*zoom,(planety[xx4]+(planetg[xx4]^0.5/2)+yp)*zoom,(planetx[greatestp[xx4]]+(planetg[greatestp[xx4]]^0.5/2)+xp)*zoom,(planety[greatestp[xx4]]+(planetg[greatestp[xx4]]^0.5/2)+yp)*zoom

Next
Next

End If


SetColor 255,0,0
DrawLine (xp-weite)*zoom,(yp-weite)*zoom,(weite+xp)*zoom,(yp-weite)*zoom
DrawLine (xp+weite)*zoom,(yp-weite)*zoom,(weite+xp)*zoom,(yp+weite)*zoom
DrawLine (xp+weite)*zoom,(yp+weite)*zoom,(xp-weite)*zoom,(yp+weite)*zoom
DrawLine (xp-weite)*zoom,(yp+weite)*zoom,(xp-weite)*zoom,(yp-weite)*zoom

Flip
Cls


If KeyDown (Key_up) Then
yp = yp + (5*1/zoom)
End If
If KeyDown (Key_down) Then
yp = yp - (5*1/zoom)
End If
If KeyDown (Key_right) Then
xp = xp - (5*1/zoom)
End If
If KeyDown (Key_left) Then
xp = xp + (5*1/zoom)
End If

If KeyDown(key_a) Then
zoom = zoom*.99
xp = xp + (4*1/zoom)
yp = yp + (3*1/zoom)

End If
If KeyDown(key_s) Then
zoom = zoom*1.01
xp = xp - (4*1/zoom)
yp = yp - (3*1/zoom)

End If

DrawRect 400,296,1,9
DrawRect 396,300,9,1

If Not KeyDown(key_right) And Not KeyDown(key_left) And Not KeyDown(key_up) And Not KeyDown (key_down) Then
SetColor 50,50,200
Else
SetColor 50,50,255
End If

DrawText "CursorKeys: Move camera",10,10

If Not KeyDown(key_s)  Then
SetColor 50,50,200
Else
SetColor 50,50,255
End If

DrawText "S: Zoom in",10,25

If Not KeyDown(key_a)  Then
SetColor 50,50,200
Else
SetColor 50,50,255
End If

DrawText "A: Zoom out",10,40

If Not KeyDown(key_space)  Then
SetColor 50,50,200
Else
SetColor 50,50,255
End If

DrawText "Space: Show planet direction",10,55

If Not KeyDown(key_g)  Then
SetColor 50,50,200
Else
SetColor 50,50,255
End If

DrawText "G:Show most important gravity connections",10,70

Until KeyHit (key_escape)
End 


Have fun with it!

Lukas

Interesting indeed. The physics are quite bad, though. The speed of a sphere after a collision should be rather the mass-weighted speed of the two spheres which fusioned and not whatever it's now.

Maybe like this:
planetxs[xx3] = (planetxs[xx3] * planetg[xx3] + planetxs[yy3] * planetg[yy3]) / ( planetg[xx3] + planetg[yy3])
planetys[xx3] = (planetys[xx3] * planetg[xx3] + planetys[yy3] * planetg[yy3]) / ( planetg[xx3] + planetg[yy3])

Of course this would have to be done after calculating the new mass.
I've done something similar before and the real challenge turned out to be creating a scenario with complex systems. Even for 3 bodies (sun-earth-moon for example) this is quite difficult and it's even more with several planets and moons at once.

With your current code 3-4 somewhat larger bodies emerge but everything dissolves after a (long) while but satellites form only very rarely. With my correction there happens what would be expected: Every piece of mass accumulates in one huge sphere, which would be the star of a planetary system. An interesting idea would be to give the bodies some kind of starting impulse, maybe orthogonal to a common central point. That would be at least a little more realistic.

Hi Steffenk,

thank you for your very useful tips!
Did you change anything else but the speed after a collision?
I know that the physics are very bad, but I don't have the knowledge about that.
Perhaps you could take a look 165-183, where the change in speed is calculated --> It's definitely wrong!
It's also not correct because my program only looks on which side the other planet is and moves there ( not with Sin,Cos)--> This also makes it unexact.

It would be very kind if you could look again over the program and perhaps post the code here.

Thank you very much,
Lukasha.

Hi!
Unluckily your program is quite confusing. I used types (and functions/methods!) when I did this and you haven't indented anything! Maybe you should try the Community Edition IDE, btw.
My first attempt maybe a year ago wasn't quite good either and also not very fast, so i'll try a new one now.

uhm.. how do i post code like you did in the first post?

You have to use:

[codebox]

...

[//codebox]

in front of the second codebox you have to use only one "/".
If I wrote it here down correct, there would be a codebox!!
;-)

Lukas