Code archives/Algorithms/2d planetary motion
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
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. | |||||
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
| ||
Oh, here is my own version, very old but funny. Keyboard commands Arrows up/down = Zoom in/out Arrows left/right = slower/faster Space = Tracers on/off F1 = inner System F2 = complete solar system F3 = double sun mass F4 = half sun mass F5 = Earth get 0.05 sun masses |
| ||
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! |
| ||
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: http://www.physics.odu.edu/~gcopelan/cai-lib/simulations.htm |
| ||
the planets go flying off when they reach the sun |
Code Archives Forum