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