module Main where import IO import Monad import Random import Pancito data Block = Outside | Distance Double frac :: Double -> Double frac z = abs (z - (fromIntegral (round z))) testBlock :: Point -> Block testBlock (x, y) = if mx > d then Outside else Distance (1 - mx / d) where d = 0.45 x' = frac x y' = frac y mx = max x' y' shadeBlock :: Double -> Block -> Colour shadeBlock t Outside = interp t grey yellow shadeBlock t (Distance d) = interp (t * d) black red middleness :: Point -> Double middleness p = 0.05 * sin (20 * t) + 1 - min 1 (d / 10.0) where (d, t) = toPolar p temperature :: Point -> Double temperature p = middleness p blocks :: Image blocks p = shadeBlock t (testBlock p) where t = temperature p clip :: Window -> Filter clip w im p = if contains w p then im p else transparent sag :: Transform sag (x, y) = (x * fx, y + dy) where m = middleness (x, y) dy = 2 * m fx = 1 - sin ((pi / 2) * (m / 7)) frame :: Window frame = ((-10.5,-7),(10.5,1)) clipFrame :: Window clipFrame = ((-9.55,-6.55),(9.55,4.55)) main = writePpmAlias 3 "blocks.ppm" 8 white (300, 120) ((-10.5,-7.5),(10.5,5)) (clip clipFrame blocks . sag)