Functions of a complex variable
It is often awkward to work in terms of 2-D physical coordinates and physical colour values when constructingPic values. A more convenient approach is to
represent pictures as mappings from the unit square in the complex plane
to normalised colour values.
Using the complex plane has several advantages: the standard Haskell module Complex
defines a useful collection of functions (including complex extensions of the common functions
of analysis) and the Haskell class mechanism can lift real literals to their complex equivalents
where necessary.
The CGraphics ('Complex Graphics') module introduces the following types and constants:
-- Type of normalised colours (R,G,B components in range 0 to 1)
type ColorF = (Float, Float, Float)
-- Normalised colour values
redF, greenF, ... :: ColorF
-- Pictures defined on the complex plane
type CPic = Complex Float -> ColorF
-- Conversion of CPic pictures to Pic (ie ordinary) pictures
-- of specified size
cPicToPic :: Int -> CPic -> Pic
Simple images
An image consisting of a red disc of radius 0.5 on a black background is represented by the function
redDisc z = if magnitude z < 0.5 then redF else blackF
It can be transformed into an ordinary (ie, Bitmap) picture of size n by n
by application of the function cPicToPic n. For example
Colour cube
A plane through the the (R,G,B) colour cube is represented by the function
spectrum (x :+ y) = ((1+x)/2, (1+y)/2, (2 -(x+y))/4)
Here, the constructor ":+" (defined in the Data.Complex library module)
is used to extract the real and imaginary components of the complex argument. The RHS of
the function definition is a triple of R/G/B colour components, each within the interval 0 to 1.
For example:
(The function toPic :: CPic -> Pic is used in subsequent examples.)
Checker-board pattern
The function
mkTiles :: Int -> ColorF -> ColorF -> CPic
generates checker-board patterns. For example:
(The checkerboard function tiles is used in subsequent examples.)
Transformations defined on the complex plane
Since pictures in this representation (ie, typeCPic) are functions, they may be
spatially transformed by post-composing them with mappings defined on the complex plane. For example,
composition with the function (* 2) doubles the scale (the cPicToPic
function tesselates the original picture as necessary), whilst composition with the
function (* exp (0 :+ theta)) rotates a picture by theta radians
(courtesy of Euler's identity). For example:
Composition with the cubing function (^ 3)) replicates an image three times
around the origin whilst composition with the exponential function, exp,
magnifies it along the x axis and rotates it along the y axis:
Conformal transforms
A conformal transformation is one that is angle-preserving. A standard result of analysis is that analytic functions are conformal. The transformations illustrated above are conformal.Swirling patterns
Swirling patterns (motivated by those illustrated in Conal Elliott's Pan system) are most naturally described in polar coordinates. A swirl transform is one in which the angle of rotation depends upon the radius. Here is such a function
swirl (r, theta) = (r, r + theta)
Use of the polar function (defined in library module Data.Complex) to convert
from Cartesian coordinates to polar ones and its inverse, the
cart function (defined in module CGraphics), to convert back again, allows
the swirl function to be expressed in Cartesian coordinates. For example:
(Note that swirls are not conformal transforms.)
Complex transforms applied to images
The above functions can, of course, be applied to pictures derived from images. The function
imageToCPic :: Pic -> CPic
(defined in the CGraphics module simply as the composition of two
of the earlier functions) converts an image to the normalised picture form.
For example, here is the swirl of a poet:
and here is the cube of a penguin . . .