haskell thread

nut 2018-03-06 11:59:02.136592 UTC

1#!/usr/bin/env stack
2{- stack
3 script
4 --resolver nightly-2018-03-06
5-}
6
7-- Draw a color wheel.
8import Graphics.Gloss
9import Control.Concurrent
10
11main = do
12 _ <- mainGame
13 r <- getLine
14 case r of
15 "yes" -> return ()
16 "" -> return ()
17
18
19
20mainGame
21 = forkOS $ animate (InWindow "Clock" (600, 600) (20, 20))
22 black frame
23
24
25-- Build the fractal, scale it so it fits in the window
26-- and rotate the whole thing as time moves on.
27frame :: Float -> Picture
28frame time
29 = Color white
30 $ Scale 120 120
31 $ Rotate (time * 2*pi)
32 $ clockFractal 5 time
33
34-- The basic fractal consists of three circles offset from the origin
35-- as follows.
36--
37-- 1
38-- |
39-- .
40-- / \
41-- 2 3
42--
43-- The direction of rotation switches as n increases.
44-- Components at higher iterations also spin faster.
45--
46clockFractal :: Int -> Float -> Picture
47clockFractal 0 s = Blank
48clockFractal n s = Pictures [circ1, circ2, circ3, lines]
49 where
50 -- y offset from origin to center of circle 1.
51 a = 1 / sin (2 * pi / 6)
52
53 -- x offset from origin to center of circles 2 and 3.
54 b = a * cos (2 * pi / 6)
55
56 nf = fromIntegral n
57 rot = if n `mod` 2 == 0
58 then 50 * s * (log (1 + nf))
59 else (-50 * s * (log (1 + nf)))
60
61 -- each element contains a copy of the (n-1) iteration contained
62 -- within a larger circle, and some text showing the time since
63 -- the animation started.
64 --
65 circNm1
66 = Pictures
67 [ circle 1
68 , Scale (a/2.5) (a/2.5) $ clockFractal (n-1) s
69 , if n > 2
70 then Color cyan
71 $ Translate (-0.15) 1
72 $ Scale 0.001 0.001
73 $ Text (show s)
74 else Blank
75 ]
76
77 circ1 = Translate 0 a $ Rotate rot circNm1
78 circ2 = Translate 1 (-b) $ Rotate (-rot) circNm1
79 circ3 = Translate (-1) (-b) $ Rotate rot circNm1
80
81 -- join each iteration to the origin with some lines.
82 lines
83 = Pictures
84 [ Line [(0, 0), ( 0, a)]
85 , Line [(0, 0), ( 1, -b)]
86 , Line [(0, 0), (-1, -b)] ]