Compute the gravity force and update the bodies accordingly
This commit is contained in:
parent
82bb1d438b
commit
4354d167ed
1 changed files with 26 additions and 19 deletions
45
src/Lib.hs
45
src/Lib.hs
|
@ -28,7 +28,6 @@ module Lib (
|
||||||
acceleration,
|
acceleration,
|
||||||
-- * Simulation
|
-- * Simulation
|
||||||
update,
|
update,
|
||||||
updateAll,
|
|
||||||
-- * Examples
|
-- * Examples
|
||||||
au, sun, earth, moon, mercury, venus, mars
|
au, sun, earth, moon, mercury, venus, mars
|
||||||
) where
|
) where
|
||||||
|
@ -207,10 +206,27 @@ field body pos =
|
||||||
r = norm vec
|
r = norm vec
|
||||||
|
|
||||||
-- | Acceleration given to a body by its neighbours
|
-- | Acceleration given to a body by its neighbours
|
||||||
acceleration :: Body -> [Body] -> V3 Double
|
acceleration :: Double -> Octree -> Body -> V3 Double
|
||||||
acceleration body = foldr f 0
|
acceleration theta tree body = case tree of
|
||||||
where f neighbour acc =
|
Empty _ -> V3 0 0 0
|
||||||
acc + field neighbour (_bodyPosition body)
|
Single _ b ->
|
||||||
|
if _bodyPosition b == _bodyPosition body then V3 0 0 0
|
||||||
|
else field b (_bodyPosition body)
|
||||||
|
Node r ned nwd swd sed neu nwu swu seu ->
|
||||||
|
let s = _regionDiameter r
|
||||||
|
vec = _regionCenterOfMass r - _bodyPosition body
|
||||||
|
d = norm vec in
|
||||||
|
if s/d < theta then
|
||||||
|
unP $ (gravity * _regionMass r / d**2) *^ normalize vec
|
||||||
|
else
|
||||||
|
acceleration theta ned body +
|
||||||
|
acceleration theta nwd body +
|
||||||
|
acceleration theta swd body +
|
||||||
|
acceleration theta sed body +
|
||||||
|
acceleration theta neu body +
|
||||||
|
acceleration theta nwu body +
|
||||||
|
acceleration theta swu body +
|
||||||
|
acceleration theta seu body
|
||||||
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
@ -219,26 +235,17 @@ acceleration body = foldr f 0
|
||||||
|
|
||||||
-- | Update speed and position
|
-- | Update speed and position
|
||||||
update :: Double -- ^ The time step
|
update :: Double -- ^ The time step
|
||||||
|
-> Double -- ^ The theta threshold parameter for Barnes-Hut
|
||||||
|
-> Octree -- ^ The Barnes-Hut Octree
|
||||||
-> Body -- ^ The body to update
|
-> Body -- ^ The body to update
|
||||||
-> [Body] -- ^ The Body's neighbours
|
|
||||||
-> Body -- ^ The updated Body
|
-> Body -- ^ The updated Body
|
||||||
update dt (Body name r m pos speed) neighbours =
|
update dt theta tree (Body name r m pos speed) =
|
||||||
Body name r m newpos newspeed
|
Body name r m newpos newspeed
|
||||||
where accel = acceleration (Body name r m pos speed) neighbours
|
where accel = acceleration theta tree (Body name r m pos speed)
|
||||||
newspeed = speed + dt *^ accel
|
newspeed = speed + dt *^ accel
|
||||||
newpos = pos + dt *^ P newspeed
|
newpos = pos + dt *^ P newspeed
|
||||||
|
|
||||||
-- | Update all bodies with a timestep dt
|
|
||||||
updateAll :: Double -> [Body] -> [Body]
|
|
||||||
updateAll dt = aux [] []
|
|
||||||
where
|
|
||||||
-- Cycles through all bodies, updates each one and stores it in
|
|
||||||
-- res. Each body already updated is moved to prev.
|
|
||||||
aux res prev [] = res
|
|
||||||
aux res prev (b:next) =
|
|
||||||
aux (newb:res) (b:prev) next
|
|
||||||
where newb = update dt b $ prev ++ next
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- EXAMPLES
|
-- EXAMPLES
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue