gloss-examples-1.9.3.1: picture/Conway/Cell.hs
module Cell where
import Graphics.Gloss
-- | A cell in the world.
data Cell
= -- | A living cell with its age
CellAlive Int
-- | A dead / blank cell.
| CellDead
deriving (Show, Eq)
-- | Sort the living from the dead.
isAlive :: Cell -> Bool
isAlive cell
= case cell of
CellAlive _ -> True
CellDead -> False
-- | The basic shape of a cell.
cellShape :: Int -> Int -> Int -> Picture
cellShape cellSize posXi posYi
= let cs = fromIntegral cellSize
posX = fromIntegral posXi
posY = fromIntegral posYi
x1 = posX
x2 = posX + cs
y1 = posY
y2 = posY + cs
in Polygon [(x1, y1), (x1, y2), (x2, y2), (x2, y1)]
-- | Convert a cell to a picture, based on a primitive shape.
-- We pass the shape in to avoid recomputing it for each cell.
pictureOfCell :: Int -> Int -> Int -> Int -> Cell -> Picture
pictureOfCell oldAge cellSize posX posY cell
= case cell of
CellAlive age -> Color (ageColor oldAge age) (cellShape cellSize posX posY)
CellDead -> Color (greyN 0.8) (cellShape cellSize posX posY)
ageColor :: Int -> Int -> Color
ageColor oldAge age
= let (r, g, b) = rampColorHotToCold 0 (fromIntegral oldAge) (fromIntegral age)
in makeColor r g b 1.0
-- Color Ramps -----------------------------------------------------------------------------------
-- | Standard Hot -> Cold hypsometric color ramp.
-- Sequence is red, yellow, green, cyan, blue.
rampColorHotToCold
:: (Ord a, Floating a)
=> a
-> a
-> a
-> (a, a, a)
rampColorHotToCold vmin vmax vNotNorm
= let
v | vNotNorm < vmin = vmin
| vNotNorm > vmax = vmax
| otherwise = vNotNorm
dv = vmax - vmin
result | v < vmin + 0.25 * dv
= ( 0
, 4 * (v - vmin) / dv
, 1.0)
| v < vmin + 0.5 * dv
= ( 0
, 1.0
, 1 + 4 * (vmin + 0.25 * dv - v) / dv)
| v < vmin + 0.75 * dv
= ( 4 * (v - vmin - 0.5 * dv) / dv
, 1.0
, 0.0)
| otherwise
= ( 1.0
, 1 + 4 * (vmin + 0.75 * dv - v) / dv
, 0)
in result