[bmx] 2d planetary motion by Nate the Great [ 1+ years ago ]

Started by BlitzBot, June 29, 2017, 00:28:39

Previous topic - Next topic

BlitzBot

Title : 2d planetary motion
Author : Nate the Great
Posted : 1+ years ago

Description : This is a little 2d planet motion simulator I made in bmax.  The damper variable is the key to slowing down or speeding up gravity and how it works. I came up with this algorithm on my own so it is not the most efficient but it works.

Code :
Code (blitzmax) Select
SuperStrict

Graphics 1440,900,0,60

Global plist:TList = New TList
Global damper:Float = .0001
Global timer:ttimer = CreateTimer(60)
Global mxspdx:Float = 0
Global mxspdy:Float = 0
Global omx:Int = MouseX()
Global omy:Int = MouseY()
planet.Create(1440/2,900/2,0,0,10000,50,255,255,0,1)
While Not KeyDown(key_escape)
Cls

mxspdx = MouseX()-omx
mxspdy = MouseY()-omy
omx = MouseX()
omy = MouseY()
DrawText mxspdx+"  "+mxspdy,1,1

updateplanets()

If MouseHit(1) Then
Local mas# = Rnd(10,20)
planet.Create(MouseX(),MouseY(),mxspdx / 30,mxspdy / 30,mas,mas*1.1,Rnd(100,255),Rnd(100,255),Rnd(100,255),.9)
EndIf

If MouseHit(2) Then
Local mas# = Rnd(10,200)
mas = mas / 200
planet.Create(MouseX(),MouseY(),mxspdx / 30,mxspdy / 30,mas,mas*1.1,Rnd(100,255),Rnd(100,255),Rnd(100,255),.9)
EndIf
WaitTimer(timer)
Flip False
Wend
End

Type planet
Field x#
Field y#
Field dx# 'velocity x
Field dy# 'velocity y
Field mass#
Field rad# 'radius
Field r:Int
Field g:Int
Field b:Int
Field alph# 'alpha
Field don:Int

Function Create:planet(x#,y#,dx#,dy#,mass#,rad#,r:Int,g:Int,b:Int,alph#)
Local p:planet = New planet
p.x = x
p.y = y
p.dx = dx
p.dy = dy
p.mass = mass
p.rad = rad
p.r = r
p.g = g
p.b = b
p.alph = alph

plist.addlast(p:planet)
End Function

Method draw()
SetColor r,g,b
SetAlpha alph#

If rad > 1 Then
DrawOval x-rad,y-rad,2*rad,2*rad
Else
Plot x,y
EndIf
End Method

Method update()
x = x + dx
y = y + dy
End Method

Method dist:Float(p:planet) 'returns distance squared
If p <> Self Then
Return (p.y - y)^2 + (p.x - x)^2
EndIf
End Method
End Type


Function updateplanets()

For Local p:planet = EachIn plist
p.draw
p.update
p.don = True
For Local p2:planet = EachIn plist
If Not p2.don Then
Local d# = p.dist(p2:planet) ' a shortcut for using 1/d^2: just dont use sqr in the distance formula and it turns into 1/d
If d > 0 Then
Local dx# = p.x - p2.x
Local dy# = p.y - p2.y
p.dx = p.dx - (dx/(d))*p2.mass*damper
p.dy = p.dy - (dy/(d))*p2.mass*damper
p2.dx = p2.dx + (dx/(d))*p.mass*damper
p2.dy = p2.dy + (dy/(d))*p.mass*damper
EndIf
EndIf
Next
Next

For Local p:planet = EachIn plist
p.don = False
Next
End Function


Comments :


Krischan(Posted 1+ years ago)

 Oh, here is my own version, very old but funny.Keyboard commandsArrows up/down = Zoom in/outArrows left/right = slower/fasterSpace = Tracers on/offF1 = inner SystemF2 = complete solar systemF3 = double sun massF4 = half sun massF5 = Earth get 0.05 sun masses
; Realistic 2D-Model of the Solar System 1.0
; considering the N-Body-Problem
; with real object data from 01/01/2000

AppTitle "Realistic 2D-Model of the Solar System 1.0"

;Parameter
scrX = 640 ; Screen width
scrY = 480 ; Screen height
scrD = 32 ; Color depth
scrT = 2 ; windows/fullscreen
pn = 10 ; Number of planets
ps = 3 ; Size of planets
zoom = 15 ; Zoom (1=far,250=near, 200=inner System, 5=complete
tracers = 1 ; planet traces (1=on, 0=off)
sunmove = 1 ; correct sun movement (1=on, 0=off)
sunmass#= 1.0 ; sun mass (1=real)
TIM# = 0 ; reset time factor
TIMINT# = 1 ; increase X days per loop, higher values cause unprecision and strange movement
; (ex. over 10 mercury gets lost)

; Gaussian gravitional constant
K1# = .01720209895
K2# = K1# * K1#

; Dim fields
Dim X#(pn), Y#(pn), Z#(pn), VX#(pn), VY#(pn), VZ#(pn), MASS#(pn), ro(pn), gr(pn), bl(pn)
Dim name$(pn), oldx#(pn), oldy#(pn), DEG#(pn), MU#(pn), SEMI#(pn), ECCEN#(pn)

; read data
Dim pla$(pn,11)
Restore planetdata
For p=0 To pn-1
For q=0 To 11
Read pla$(p,q)
name$(p)=pla$(p,0) ; Name
X#(p)=pla$(p,1) ; X-Position
Y#(p)=pla$(p,2) ; Y-Position
Z#(p)=pla$(p,3) ; Z-Position
VX#(p)=pla$(p,4) ; Speed X
VY#(p)=pla$(p,5) ; Speed Y
VZ#(p)=pla$(p,6) ; Speed Z
MASS#(p)=Float(pla$(p,7))*10^Int(pla$(p,8)) ; Mass
ro(p)=pla$(p,9) ; Red
gr(p)=pla$(p,10) ; Green
bl(p)=pla$(p,11) ; Blue
Next
Next

.planetdata
;    Name              POS X         POS Y         POS Z             Vx             Vy             Vz    Mass*10^X   Red   Gre   Blu
Data "Sun"     ,   0.0000000 ,   0.0000000 ,   0.0000000 ,  0.000000000 ,  0.000000000 ,  0.000000000 , 1.991 , 30 , 255 , 255 ,   0
Data "Mercury" ,  -0.1778023 ,  -0.3863251 ,  -0.1879025 ,  0.020335410 , -0.007559570 , -0.006147710 , 3.191 , 23 , 255 ,  64 ,   0
Data "Venus"   ,   0.1787301 ,  -0.6390267 ,  -0.2987722 ,  0.019469170 ,  0.004915870 ,  0.000978980 , 4.886 , 24 , 255 , 192 , 128
Data "Earth"   ,  -0.3305873 ,   0.8497269 ,   0.3684325 , -0.016483420 , -0.005365460 , -0.002326460 , 5.979 , 24 ,   0 ,   0 , 255
Data "Mars"    ,  -1.5848092 ,  -0.3648638 ,  -0.1244522 ,  0.003821510 , -0.011241840 , -0.005259630 , 6.418 , 23 , 255 ,   0 ,   0
Data "Jupiter" ,   4.1801700 ,  -2.5386080 ,  -1.1900210 ,  0.004106423 ,  0.006125327 ,  0.002525539 , 1.901 , 27 , 128 , 255 ,   0
Data "Saturn"  ,  -4.6197080 ,  -8.2374610 ,  -3.2033610 ,  0.004647751 , -0.002328957 , -0.001161564 , 5.684 , 26 , 255 , 255 , 128
Data "Uranus"  ,  -3.7245900 , -17.1975200 ,  -7.4791700 ,  0.003833665 , -0.000845721 , -0.000424809 , 8.682 , 25 ,   0 , 255 , 255
Data "Neptun"  ,   1.9138100 , -27.9215500 , -11.4762000 ,  0.003118271 ,  0.000233303 ,  0.000017967 , 1.027 , 26 ,   0 , 128 , 255
Data "Pluto"   , -23.2285900 , -18.5272000 ,   1.2167500 ,  0.002066577 , -0.002488884 , -0.001397200 , 1.080 , 24 , 128 , 128 , 128

goto skip
; randomized planets (experimental)
SeedRnd MilliSecs()
For i=1 To pn-1
speed#=(1/Exp(i)*500+1500/Sqr(i+2.7))-50
X#(i)=-i-Rnd(-.2,.2)
Y#(i)=-i-Rnd(-.2,.2)
Z#(i)=0
VX#(i)=-speed#/100000
VY#(i)=speed#/100000
VZ#(i)=0
Next
.skip
; normalize masses with sun mass
For I = 1 To pn-1
MASS#(I) = MASS#(I) / MASS(0)
Next
MASS#(0) = sunmass#

; create reduced mass in gaussian units
For I = 1 To pn-1
MU#(I) = K2# * (1 + MASS#(I))
Next

; init GFX
Graphics scrX,scrY,scrD,scrT
SetBuffer BackBuffer()

; main loop
While Not KeyHit(1)

; increase time by factor
TIM# = TIM# + TIMINT#

; draw traces
For i=0 To pn-1
If tracers Then Color 32,32,32 Else Color 0,0,0
Oval(scrX/2+oldx#(i),scrY/2+oldy#(i),ps,ps,1)
Next

; calculation and GFX output
Gosub NewV
Gosub NewP

Rect 0,0,150,42,1
Color 255,255,255

Text 0, 0,"Days:  "+Int(TIM#)
Text 0,10,"Years: "+TIM#/365.25
Text 0,20,"Time:  "+TIMINT#
Text 0,30,"Zoom:  "+zoom

kp=0
If KeyDown(200) Then zoom=zoom+1:If zoom>250 Then zoom=250
If KeyDown(208) Then zoom=zoom-1:If zoom<1 Then zoom=1
If KeyDown(203) Then TIMINT#=TIMINT#-.5:If TIMINT#<.5 Then TIMINT#=.5
If KeyDown(205) Then TIMINT#=TIMINT#+.5:If TIMINT#>25 Then TIMINT#=25
If KeyHit(57) Then tracers=1-tracers:Cls
If KeyDown(59) Then zoom=200:Cls
If KeyDown(60) Then zoom=5:Cls
If KeyDown(61) Then MASS#(0)=2
If KeyDown(62) Then MASS#(0)=0.5
If KeyDown(63) Then MASS#(3)=.05

Flip 1

Wend

End

; calculate new speed
.NewV
For I = 0 To pn-1

AX# = 0
AY# = 0
AZ# = 0

For J = 0 To pn-1
If (J = I) Then Goto weiter
XJI# = X#(J) - X#(I)
YJI# = Y#(J) - Y#(I)
ZJI# = Z#(J) - Z#(I)
R# = Sqr(ZJI# * ZJI# + YJI# * YJI# + XJI# * XJI#)
R3# = R# * R# * R#
COEFF# = K2# * MASS#(J) / R3#
AX# = COEFF# * XJI# + AX#
AY# = COEFF# * YJI# + AY#
AZ# = COEFF# * ZJI# + AZ#
.weiter
Next

VX#(I) = VX#(I) + AX# * TIMINT#
VY#(I) = VY#(I) + AY# * TIMINT#
VZ#(I) = VZ#(I) + AZ# * TIMINT#
Next
Return

; calculate new position
.NewP
For i=0 To pn-1

; calculate current position
X#(i) = X(i) + VX#(i) * TIMINT#
Y#(i) = Y(i) + VY#(i) * TIMINT#
Z#(i) = Z(i) + VZ#(i) * TIMINT#

; consider zoom
sx#=X#(i)*zoom
sy#=Y#(i)*zoom

; correct sun movement
If i=0 And sunmove=1 Then
sunx#=sx#
suny#=sy#
EndIf

; new Position with zoom and sun correction
sx#=sx#-sunx#
sy#=sy#-suny#

; save old position for tracers
oldx#(i)=sx#
oldy#(i)=sy#

; draw planets
Color ro(i),gr(i),bl(i)
Oval(scrX/2+sx#,scrY/2+sy#,ps,ps,1)
Next
Return



Nate the Great(Posted 1+ years ago)

 haha thats pretty cool!so if the sun's mass is doubled and then when the earth is going fastest, it is halfed, the earth is shot away and never comes back!


Krischan(Posted 1+ years ago)

 The problem is that the precision gets lost if you increase the time too much. In reality, a 15-meter measurement inaccuracy of earth's orbit will lead to a 100% prediction loss of earth's orbit in 100 Million years! And Blitz only has 6 decimal places precision.A step of 1 is one second per day (approx.), a step of 1/3600 = 0.0002777 is more real but very boring to watch :-)Oh if somebody is interested in these mathematics, here is a nice website with many (Quick-)Basic sources:<a href="http://www.physics.odu.edu/~gcopelan/cai-lib/simulations.htm" target="_blank">http://www.physics.odu.edu/~gcopelan/cai-lib/simulations.htm</a>


slenkar(Posted 1+ years ago)

 the planets go flying off when they reach the sun [/i]