hgl-example-0.0.2: src/GraphicDemo.hs
module GraphicDemo where
import Graphics.HGL.Units (Time, Point, Size, )
import Graphics.HGL.Draw.Monad (Graphic, )
import Graphics.HGL.Utils
import Graphics.HGL.Draw.Pen
import Graphics.HGL.Draw.Text
import Graphics.HGL.Draw.Picture
import Graphics.HGL.Window
import Graphics.HGL.Run
import Control.Exception (bracket, )
import Prelude hiding ((^), )
import qualified Prelude as P
-- see HTam.Useful
(^) :: Num a => a -> Int -> a
(^) = (P.^)
aufTasteWarten :: IO ()
aufTasteWarten =
runWindow "graphic demo" (400,300) getKey
test :: Graphic -> IO ()
test graphic =
runWindow "graphic demo" (500,500) (\w -> setGraphic w graphic >> getKey w)
testText :: IO ()
testText =
test (text (10,10) "test")
runWindowEx ::
Title ->
Maybe Point ->
Size ->
RedrawMode ->
Maybe Time ->
(Window -> IO ()) ->
IO ()
runWindowEx title position size drawMode timerUnit act =
runGraphics $
bracket
(openWindowEx title position size drawMode timerUnit)
closeWindow
act
testAnim :: Time -> [Graphic] -> IO ()
testAnim dur frames =
runWindowEx "graphic demo" Nothing (500,500) DoubleBuffered (Just dur) $
\w ->
-- w <- openWindow "graphic demo" (500,500)
-- setGraphic w (text (10,10) "test")
mapM_ (\frame -> setGraphic w frame >> getWindowTick w) frames
-- getKey w
textAnim :: IO ()
textAnim =
testAnim 20 (map (\pos -> text (pos,2*pos) "test") [0..])
dreieck :: IO ()
dreieck =
test (polyline [(0,0),(100,100),(200,0)])
siebzehneck :: IO ()
siebzehneck =
test (polygon (map (\i ->
let angle = (fromInteger i /17*2*pi)::Double
in (250+round(200*cos angle),250+round(200*sin angle))) [0..16]))
spirale :: IO ()
spirale =
test (polyline (map (\i ->
let angle = (fromInteger i / 200 * 2*pi)::Double
in (250+round(10*angle*cos angle),250+round(10*angle*sin angle))) [0..1000]))
spiralenpunkte :: Double -> [(Int,Int)]
spiralenpunkte anfang =
map (\i ->
let angle = (fromInteger i / 20 * 2*pi)::Double
in (250+round(10*angle*cos (anfang+angle)),
250+round(10*angle*sin (anfang+angle)))) [0..100]
spiralenpunkteGleichmaessig :: Double -> [(Int,Int)]
spiralenpunkteGleichmaessig anfang =
let angleList = take 100 $
iterate (\angle -> angle + 9 * recip (25 + angle)) 0
in map (\angle ->
(250+round(10*angle*cos(anfang+angle)),
250+round(10*angle*sin(anfang+angle)))) angleList
doppelSpirale :: IO ()
doppelSpirale =
test (overGraphics
[polyline (spiralenpunkte 0),
polyline (spiralenpunkte (4*pi/3)),
polyline (spiralenpunkte (2*pi/3))])
spiraleAnim :: IO ()
spiraleAnim =
testAnim 20
(map (\phase -> polyline (spiralenpunkteGleichmaessig phase))
[0,(-0.1)..])
lissajous :: IO ()
lissajous =
test (polyline (map (\i ->
let angle = (fromInteger i / 200 * 2*pi)::Double
in (250+round(200*sin (2*angle)),
250+round(200*sin angle))) [0..200]))
{- Warten mit Standard-UNIX-Funktionen geht irgendwie nicht.
lissajousAnim =
withWindow "graphic demo" (500,500) (\w -> mapM_ (\phase -> runGraphics (setGraphic w (polyline (map(\i -> let angle = (fromInteger i / 50 * 2*pi)::Double in (250+round(200*sin (angle)),250+round(200*sin (2*angle+phase)))) [0..50])) >> usleep 20000)) [0,0.1..])
-}
lissajousAnim :: IO ()
lissajousAnim =
testAnim 20
(map (\phase -> polyline
(map(\i ->
let angle = (fromInteger i / 100 * 2*pi)::Double
in (250+round(200*sin (2.3*(angle+phase)+phase)),
250+round(200*sin (3*(angle+phase))))) [0..100]))
[0,0.05..])
kreispunkte :: (Double, Double) -> Double -> Int -> Double -> Double
-> [(Double, Double)]
kreispunkte (mx,my) radius n start inc =
map (\angle ->
let x = mx + radius * cos angle
y = my + radius * sin angle
in (x, y))
(take n (iterate (inc+) start))
roundPoint :: (Double, Double) -> Point
roundPoint (x,y) = (round x, round y)
sternAnim :: IO ()
sternAnim =
runWindowEx "graphic demo" Nothing (500,500) DoubleBuffered (Just 33) $
\w -> do
let rgbs = map (\green -> RGB 255 green 0) [0,5..255]
pens <- sequence (zipWith (createPen Solid) (map (flip div 5) [0..]) rgbs)
mapM_ (\phase -> setGraphic w (
let size = (1 + sin (3*phase)) / 2
in selectPen (pens !! round (size * fromIntegral (length pens - 1)))
>> polyline (map roundPoint
(kreispunkte (250,250) (40 + 160*size) 10 phase (8/9*pi))))
>> getWindowTick w) [0,0.03..]
sternenkreisAnim :: IO ()
sternenkreisAnim =
let stern phase m =
polygon (map roundPoint (kreispunkte m 50 6 phase (2*2*pi/5)))
in testAnim 20
(map (\phase -> overGraphics
(map (stern (-phase))
(kreispunkte (250, 250) 150 7 phase (2*pi/7))))
[0,0.02..])