brillo-examples-1.13.3: picture/Conway/Cell.hs
module Cell where
import Brillo
-- | 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