-- Pivotal 0.025 27.10.05 module CGraphics( module Pic, ColorF, redF, greenF, blueF, yellowF, whiteF, blackF, CPic, bitmapToCPic, imageToCPic, cPicToPic, cart, blend ) where import Pic import Graphics.UI.Gtk import Data.Complex import Data.Word -- Functions for plotting functions of a complex variable -- Normalised color values type ColorF = (Float, Float, Float) convert :: Color -> ColorF convert (Color r g b) = (fromIntegral r / wordMax, fromIntegral g / wordMax, fromIntegral b / wordMax) redF, greenF, blueF, whiteF, blackF :: ColorF blackF = convert black redF = convert red greenF = convert green blueF = convert blue yellowF = convert yellow whiteF = convert white wordMax :: Float wordMax = fromIntegral (maxBound :: Word16) -- Conversion from Polar to Cartesian coordinates (the inverse of the "polar" fn) cart :: (Float, Float) -> Complex Float cart (r, th) = realToFrac r * cis th -- Pictures represented by a function of a complex variable type CPic = Complex Float -> ColorF -- Function to convert function of a complex variable to a picture bitmap -- The domain of the complex variable is (|x| <= 1) && (|y| <= 1) -- The width and the height of the plot are as specified by first arg cPicToPic :: Int -> CPic -> Pic cPicToPic size f = Trans 0 20 $ -- Displace it downwards Bitmap size size (\ x y -> let u = fromIntegral (2 * x) / fromIntegral size - 1.0 :: Float v = fromIntegral (2 * y) / fromIntegral size - 1.0 :: Float (red, green, blue) = f (u :+ v) r' = round (wordMax * (red `min` 1.0)) -- Prevent overflow g' = round (wordMax * (green `min` 1.0)) b' = round (wordMax * (blue `min` 1.0)) in Color r' g' b') -- Bitmap to CPic conversion bitmapToCPic :: Pic -> CPic bitmapToCPic (Bitmap w h f) (x :+ y) = let k = fromIntegral (max w h) x' = round ((fromIntegral w + x * k) / 2.0) y' = round ((fromIntegral h + y * k) / 2.0) c = f x' y' in convert c -- Image to CPic conversion imageToCPic :: Pic -> CPic imageToCPic = bitmapToCPic . imageToBitmap -- Blending of two colours blend :: Float -> ColorF -> ColorF -> ColorF blend k (r1, g1, b1) (r2, g2, b2) = let k' = max 0 (min 1 k) h' = 1 - k' in (k' * r1 + h' * r2, k' * g1 + h' * g2, k' * b1 + h' * b2)