Add command line arguments
This commit is contained in:
parent
fac591fb51
commit
439e065574
3 changed files with 72 additions and 10 deletions
78
app/Main.hs
78
app/Main.hs
|
@ -10,6 +10,9 @@ import Control.Monad (replicateM)
|
||||||
|
|
||||||
import Graphics.Gloss hiding (Point)
|
import Graphics.Gloss hiding (Point)
|
||||||
|
|
||||||
|
import Options.Applicative
|
||||||
|
import Data.Semigroup ((<>))
|
||||||
|
import Safe
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- Random body generation
|
-- Random body generation
|
||||||
|
@ -78,6 +81,65 @@ csvFromInit :: Int -- ^ The number of time steps to keep
|
||||||
-> String -- ^ CSV data
|
-> String -- ^ CSV data
|
||||||
csvFromInit n dt theta b = concat $ map (uncurry csvFromBodies) (take n $ steps dt theta b)
|
csvFromInit n dt theta b = concat $ map (uncurry csvFromBodies) (take n $ steps dt theta b)
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- Commandline arguments
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
data CmdLineOptions = CmdLineOptions
|
||||||
|
{ optionNumberBodies :: Int
|
||||||
|
, optionColor :: Color
|
||||||
|
, optionFPS :: Int
|
||||||
|
}
|
||||||
|
|
||||||
|
numberBodiesParser :: Parser Int
|
||||||
|
numberBodiesParser = option auto
|
||||||
|
(long "number-bodies"
|
||||||
|
<> short 'n'
|
||||||
|
<> help "Number of Bodies"
|
||||||
|
<> showDefault
|
||||||
|
<> value 300
|
||||||
|
<> metavar "N")
|
||||||
|
|
||||||
|
fpsParser :: Parser Int
|
||||||
|
fpsParser = option auto
|
||||||
|
(long "fps"
|
||||||
|
<> help "Frame rate"
|
||||||
|
<> showDefault
|
||||||
|
<> value 25
|
||||||
|
<> metavar "FPS")
|
||||||
|
|
||||||
|
splitOn :: Char -> String -> [String]
|
||||||
|
splitOn c s = case dropWhile (== c) s of
|
||||||
|
"" -> []
|
||||||
|
s' -> w : splitOn c s''
|
||||||
|
where (w, s'') = break (== c) s'
|
||||||
|
|
||||||
|
colorParser :: Parser Color
|
||||||
|
colorParser = option (eitherReader readRGB)
|
||||||
|
(long "color"
|
||||||
|
<> short 'c'
|
||||||
|
<> help "Foreground color RGBA (0-255)"
|
||||||
|
<> showDefault
|
||||||
|
<> value white
|
||||||
|
<> metavar "R,G,B")
|
||||||
|
where readRGB s =
|
||||||
|
case mapM readEitherSafe $ splitOn ',' s of
|
||||||
|
Right (r:g:b:a:_) -> Right $ makeColorI r g b a
|
||||||
|
Right (r:g:b:_) -> Right $ makeColorI r g b 255
|
||||||
|
Right (r:g:_) -> Right $ makeColorI r g 255 255
|
||||||
|
Right (r:_) -> Right $ makeColorI r 255 255 255
|
||||||
|
Right _ -> Right $ makeColorI 255 255 255 255
|
||||||
|
Left s -> Left s
|
||||||
|
|
||||||
|
optionsParser :: Parser CmdLineOptions
|
||||||
|
optionsParser = CmdLineOptions <$>
|
||||||
|
numberBodiesParser <*> colorParser <*> fpsParser
|
||||||
|
|
||||||
|
opts :: ParserInfo CmdLineOptions
|
||||||
|
opts = info (optionsParser <**> helper)
|
||||||
|
(fullDesc
|
||||||
|
<> progDesc "Barnes-Hut N-body simulator"
|
||||||
|
<> header "orbit")
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- Gloss
|
-- Gloss
|
||||||
|
@ -92,22 +154,20 @@ window :: Display
|
||||||
window = InWindow "Orbit" (width, height) (offset, offset)
|
window = InWindow "Orbit" (width, height) (offset, offset)
|
||||||
|
|
||||||
displayBody :: Body -> Picture
|
displayBody :: Body -> Picture
|
||||||
displayBody b = translate (realToFrac x) (realToFrac y) $ circle (realToFrac (_bodyRadius b))
|
displayBody b = translate (realToFrac x) (realToFrac y) $ circleSolid (realToFrac (_bodyRadius b))
|
||||||
where P (V3 x y _) = _bodyPosition b
|
where P (V3 x y _) = _bodyPosition b
|
||||||
|
|
||||||
displayBodies :: [Body] -> Picture
|
displayBodies :: Color -> [Body] -> Picture
|
||||||
displayBodies = color white . Pictures . map displayBody
|
displayBodies c = color c . Pictures . map displayBody
|
||||||
|
|
||||||
drawing :: Picture
|
|
||||||
drawing = color white $ circle 80
|
|
||||||
|
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
main = do
|
main = do
|
||||||
bodies <- replicateM 300 randomBody
|
CmdLineOptions n c fps <- execParser opts
|
||||||
|
bodies <- replicateM n randomBody
|
||||||
simulate
|
simulate
|
||||||
window
|
window
|
||||||
black
|
black
|
||||||
25
|
fps
|
||||||
bodies
|
bodies
|
||||||
displayBodies
|
(displayBodies c)
|
||||||
(\_ dt bs -> updateAll (realToFrac dt*1e6) 0.5 bs)
|
(\_ dt bs -> updateAll (realToFrac dt*1e6) 0.5 bs)
|
||||||
|
|
|
@ -32,6 +32,8 @@ executable orbit-exe
|
||||||
, linear
|
, linear
|
||||||
, random
|
, random
|
||||||
, gloss
|
, gloss
|
||||||
|
, optparse-applicative
|
||||||
|
, safe
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
|
|
||||||
test-suite orbit-test
|
test-suite orbit-test
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
# resolver:
|
# resolver:
|
||||||
# name: custom-snapshot
|
# name: custom-snapshot
|
||||||
# location: "./custom-snapshot.yaml"
|
# location: "./custom-snapshot.yaml"
|
||||||
resolver: lts-9.10
|
resolver: lts-10.3
|
||||||
|
|
||||||
# User packages to be built.
|
# User packages to be built.
|
||||||
# Various formats can be used as shown in the example below.
|
# Various formats can be used as shown in the example below.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue