hps-0.1: Help/Animation.hs
module Animation where
import System.Random
import Graphics.PS
import Graphics.PS.Cairo
import qualified Graphics.UI.Gtk as G
import Data.IORef
data A = A Double Double Double Double
semiann :: A -> Double -> Image
semiann (A gs ir xr a) sa =
let x = 250
y = 250
z = 250
sa' = sa * 2.0 * pi
a' = a * pi
ir' = min ir xr
xr' = max ir xr
shift = translate x y . scale z z
in Fill (greyGS gs) (shift (annular origin ir' xr' sa' a'))
-- | Group a list into a list of n element lists.
clump :: Int -> [a] -> [[a]]
clump _ [] = []
clump n l =
let (i,j) = splitAt n l
in i : clump n j
-- | Generate a list of n random numbers in the range [l,r].
randn :: Int -> Int -> Double -> Double -> [Double]
randn s n l r =
let f i = i * (r - l) + l
in (map f . take n . randoms . mkStdGen) s
--
settings :: [(A, Double, Double)]
settings =
let g [a,b,c,d,e,f] = (A a b c d, e, f)
g _ = undefined
in map g (clump 6 (randn 0 66 0 1))
as :: [A]
as = map (\(a,_,_) -> a) settings
ns :: [Double]
ns = map (\(_,n,_) -> n/100) settings
is :: [Double]
is = map (\(_,_,i) -> i) settings
main :: IO ()
main = do
G.initGUI
window <- G.windowNew
canvas <- G.drawingAreaNew
ss <- newIORef is
G.windowSetResizable window False
G.widgetSetSizeRequest window 500 500
G.onKeyPress window (const (G.widgetDestroy window >> return True))
G.onDestroy window G.mainQuit
G.onExpose canvas (const (updateCanvas canvas ss))
G.timeoutAdd (G.widgetQueueDraw window >> return True) 42
G.set window [G.containerChild G.:= canvas]
G.widgetShowAll window
G.mainGUI
updateCanvas :: G.DrawingArea -> IORef [Double] -> IO Bool
updateCanvas canvas ss = do
window <- G.widgetGetDrawWindow canvas
modifyIORef ss (zipWith (+) ns)
aa <- readIORef ss
let i = foldl1 over (zipWith semiann as aa)
G.renderWithDrawable window (renderImage i)
return True