--
import Shape
import Draw
import Region
import Picture
import SOEGraphics hiding (Region)
import qualified SOEGraphics as G (Region)
import Win32Misc (timeGetTime)
import Word (Word32)
-------------- The animation stuff ----------
word32ToInt :: Word32 -> Int
word32ToInt x = fromInteger(toInteger x)
type Animation a = Time -> a
type Time = Float
rubberBall :: Animation Shape
rubberBall t = Ellipse (sin t) (cos t)
revolvingBall :: Animation Region
revolvingBall t
 = let ball = Shape (Ellipse 0.2 0.2)
 in Translate (sin t, cos t) ball
planets :: Animation Picture
planets t
 = let p1 = Region Red (Shape (rubberBall t))
 p2 = Region Yellow (revolvingBall t)
 in p1 `Over` p2
tellTime :: Animation String
tellTime t = "The time is: " ++ show t
{-
openWindowEx :: String -> Maybe Point -> Maybe Point ->
 (Graphic -> DrawFun) -> Maybe Word32 ->
 IO Window
-}
animate :: String -> Animation a -> (a -> IO Graphic) -> IO ()
animate title anim toGraphic
 = runGraphics (
 do w <- openWindowEx title (Just (0,0)) (Just (xWin,yWin)) drawBufferedGraphic (Just 30) t0 <- timeGetTime let loop = do t <- timeGetTime -- print ("the time is" ++ (show t)) let ft = intToFloat (word32ToInt (t-t0)) / 1000 -- print "past let" gr <- toGraphic (anim ft) -- print "past toGraphic" setGraphic w gr getWindowTick w loop loop ) main1 = animate "Animation of a Shape" rubberBall (return . withColor Blue . shapeToGraphic) main2 = animate "Animated Text" tellTime (return . text (100,200)) main3 = animate "Animated Region" revolvingBall (\r -> return (withColor Yellow
 (regionToGraphic r)))
main4 = animate "Animated Picture" planets (return.picToGraphic)
main4a :: IO ()
main4a = animate "Experiment" both (return.picToGraphic)
 where both t = Over (Text (1,2) (tellTime t)) (planets t)
regionToGraphic :: Region -> Graphic
regionToGraphic = drawRegion . regionToGRegion
picToGraphic :: Picture -> Graphic
picToGraphic (Region c r)
 = withColor c (regionToGraphic r)
picToGraphic (p1 `Over` p2)
 = picToGraphic p1 `overGraphic` picToGraphic p2
picToGraphic (Text v str) = (text (trans v) str)
picToGraphic EmptyPic = emptyGraphic
type Anim = Animation Picture
emptyA :: Anim
emptyA t = EmptyPic
overA :: Anim -> Anim -> Anim
overA a1 a2 t = a1 t `Over` a2 t
overManyA :: [Anim] -> Anim
overManyA = foldr overA emptyA
-- timeTransA :: (Time -> Time) -> Animation a -> Animation a
timeTransA :: Animation Time -> Animation a -> Animation a
-- timeTransA f a t = a (f t)
timeTransA f a = a . f
{-
 timeTransA (2*) anim
 timeTransA (5+) anim
 timeTransA negate anim
-}
rBall :: Anim
rBall t = let ball = Shape (Ellipse 0.2 0.2)
 in Region Red (Translate (sin t, cos t) ball)
rBalls :: Anim
rBalls = overManyA [ timeTransA ((t*pi/4)+) rBall | t <- [0..7]] main5 = animate "Lots of Balls" rBalls (return . picToGraphic) ------- Type Classes and Animations --------- newtype Behavior a = Beh (Time -> a)
lift0 :: a -> Behavior a
lift0 x = Beh (\t -> x)
lift1 :: (a -> b) -> (Behavior a -> Behavior b)
lift1 f (Beh a)
 = Beh (\t -> f (a t))
lift2 :: (a -> b -> c) -> (Behavior a -> Behavior b -> Behavior c)
lift2 g (Beh a) (Beh b)
 = Beh (\t -> g (a t) (b t))
lift3 :: (a -> b -> c -> d) ->
 (Behavior a -> Behavior b -> Behavior c -> Behavior d)
lift3 g (Beh a) (Beh b) (Beh c)
 = Beh (\t -> g (a t) (b t) (c t))
instance Eq (Behavior a) where
 a1 == a2 = error "Can't compare animations."
instance Show (Behavior a) where
 showsPrec n a1 = error "Can't coerce animation to String."
instance Num a => Num (Behavior a) where
 (+) = lift2 (+); (*) = lift2 (*)
 negate = lift1 negate; abs = lift1 abs
 signum = lift1 signum
 fromInteger = lift0 . fromInteger
instance Fractional a => Fractional (Behavior a) where
 (/) = lift2 (/)
 fromRational = lift0 . fromRational
instance Floating a => Floating (Behavior a) where
 pi = lift0 pi; sqrt = lift1 sqrt
 exp = lift1 exp; log = lift1 log
 sin = lift1 sin; cos = lift1 cos
 tan = lift1 tan
 asin = lift1 asin; acos = lift1 acos
 atan = lift1 atan
 sinh = lift1 sinh; cosh = lift1 cosh
 tanh = lift1 tanh
 asinh = lift1 asinh; acosh = lift1 acosh
 atanh = lift1 atanh
time :: Behavior Time
time = Beh (\t -> t)
instance Ani [a] where
 empty = []
 over = (++)
instance Ani (Fun a) where
 empty = Fun id
 Fun a `over` Fun b = Fun (a . b)
data Fun a = Fun (a->a)
class Ani a where
 empty :: a
 over :: a -> a -> a
instance Ani a => Ani (Float -> a) where
 empty t = empty
 over f g t = over (f t) (g t)
instance Ani Picture where
 empty = EmptyPic
 over = Over
instance Ani a => Ani (Behavior a) where
 empty = lift0 empty
 over = lift2 over
overMany :: Ani a => [a] -> a
overMany = foldr over empty
m :: Behavior Picture
m = let a = lift0 (empty `over` p)
 in a `over` empty
p :: Picture
p = empty
timeTrans (Beh t) (Beh a) = Beh (timeTransA t a)
reg = lift2 Region
shape = lift1 Shape
ell = lift2 Ellipse
red = lift0 Red
blue = lift0 Blue
translate (Beh a1, Beh a2) (Beh p)
 = Beh (\t -> Translate (a1 t, a2 t) (p t))
rBall2 :: Behavior Picture
rBall2
 = let ball = shape (ell 0.2 0.2)
 in reg red (translate (sin time, cos time) ball)
(>*) :: Ord a => Behavior a -> Behavior a -> Behavior Bool
(>*) = lift2 (>)
ifFun :: Bool -> a -> a -> a
ifFun p c a = if p then c else a
cond :: Behavior Bool -> Behavior a -> Behavior a -> Behavior a
cond = lift3 ifFun
rb :: Behavior Color
rb = cond (sin time>* 0) red blue
animate2 :: String -> Behavior Picture -> IO ()
animate2 s (Beh pf) =
 animate s pf (return . picToGraphic)
main6 = animate2 "Wild" rBall2
----- Kaleidoscope example
class Turnable a where
 turn :: Float -> a -> a
instance Turnable Picture where
 turn theta (Region c r) = Region c (turn theta r) -- turn on Regions
 turn theta (p1 `Over` p2) = turn theta p1 `Over` turn theta p2
 turn theta EmptyPic = EmptyPic
instance Turnable a => Turnable (Behavior a) where
 turn theta (Beh b) = Beh(turn theta . b)
rotate :: Float -> Coordinate -> Coordinate
rotate theta (x,y) =
 (x*c + y*s, y*c - x*s)
 where (s,c) = (sin theta,cos theta)
instance Turnable Shape where
 turn theta (Polygon ps) = Polygon (map (rotate theta) ps)
 -- lots of missing cases here for
 -- turn theta (Rectangle s1 s2) =
 -- turn theta (Ellipse r1 r2) =
 -- turn theta (RtTriangle s1 s2) =
instance Turnable Region where
 turn theta (Shape sh) = Shape (turn theta sh)
 -- lots of missing cases here for
 -- turn theta (Translate (u,v) r) =
 -- turn theta (Scale (u,v) r) =
 -- turn theta (Complement r) =
 -- turn theta (r1 `Union` r2) =
 -- turn theta (r1 `Intersect` r2) =
 -- turn theta Empty = Empty
spectrum = [ c | c <- [minBound..], c/= Black] -- All colors but black slowTime = 0.1 * time kaleido :: Integer -> (Float -> Behavior Coordinate) -> Behavior Picture
kaleido n f =
 lift2 turn (pi * sin slowTime)
 (overMany (zipWith reg (map lift0 (cycle spectrum))
 (map (flip turn poly) rads)))
 where rads = map (((2 * pi/fromInteger n)*).fromInteger) [0..n-1]
 poly = polyShapeAnim (map f rads)
polyShapeAnim :: [Behavior Coordinate] -> Behavior Region
polyShapeAnim = lift1 (Shape . Polygon).synclist
 where synclist :: [Behavior a] -> Behavior[a]
 synclist l = Beh(\t -> map (\(Beh f) -> f t) l)
syncPair :: (Behavior a,Behavior b) -> Behavior(a,b)
syncPair (Beh f,Beh g) = Beh(\t -> (f t,g t))
kaleido1 = kaleido 6 star
 where star x = syncPair (2*cos(v*c+l),2 * abs(sin(slowTime * s - l)))
 where v = lift0 x
 l = v * (slowTime + 1)
 (s,c) = (sin l,cos l)
animateB :: String -> Behavior Picture -> IO ()
animateB s (Beh x) = animate s x
 (return . picToGraphic)
main7 = animateB "kaleido1" kaleido1
-- 

AltStyle によって変換されたページ (->オリジナル) /