Build a Barnes-Hut tree

This commit is contained in:
Dimitri Lozeve 2017-11-09 18:02:21 +00:00
parent 2cca4a45ef
commit 57ddd56775

View file

@ -22,6 +22,7 @@ module Lib (
subOctree, subOctree,
updateRegion, updateRegion,
insertBody, insertBody,
buildTree,
-- * Gravity force -- * Gravity force
field, field,
acceleration, acceleration,
@ -32,6 +33,9 @@ module Lib (
au, sun, earth, moon, mercury, venus, mars au, sun, earth, moon, mercury, venus, mars
) where ) where
import Data.List
import Data.Foldable
import Linear.Vector import Linear.Vector
import Linear.V3 import Linear.V3
import Linear.Affine import Linear.Affine
@ -164,6 +168,27 @@ insertBody b t = case t of
SEU -> Node r' ned nwd swd sed neu nwu swu (insertBody b seu) SEU -> Node r' ned nwd swd sed neu nwu swu (insertBody b seu)
-- | Build a Barnes-Hut Octree from a list of Bodies
buildTree :: [Body] -> Octree
buildTree bs = foldr insertBody (Empty r) bs
where r = Region { _regionCenter = center,
_regionCenterOfMass = center,
_regionMass = 0,
_regionDiameter = diameter
}
-- We determine the initial center and diameter of the region
-- using the positions of all input bodies.
positions :: [Point V3 Double]
positions = map (flip (^.) bodyPosition) bs
-- The center is just the geometric center of all positions.
center :: Point V3 Double
center = (sum $ positions) ^/ (fromIntegral $ length positions)
-- The diameter is the maximum range of the coordinates. This
-- is roughly 2x more what is needed.
diameter :: Double
diameter = maximum $ map (\xs -> maximum xs - minimum xs) $ transpose $ map toList positions
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- GRAVITY FORCE -- GRAVITY FORCE
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------