generative-art-0.1.0.0
Safe HaskellSafe-Inferred
LanguageHaskell2010

Geometry.Algorithms.Contour

Synopsis

Documentation

isoLines Source #

Arguments

:: Grid 
-> (Vec2 -> Double)

Scalar field

-> Double

Contour threshold

-> [[Vec2]]

Contours of the field

Find the iso lines of a function (= where the function has the same height, like e.g. height lines on a map) within a certain Grid (which unifies size and resolution).

This function can be partially applied to cache the function values when drawing iso lines, which is especially useful if repeatedly sampling the function is expensive:

-- BAD! Recalculates the values of f across the grid for each invocation
isosBad = [isoLines grid f isoHeight | isoHeight <- [1..10]]

-- Good: Calculates the value table only once
isosGood = let iso = isoLines grid f
             in [iso isoHeight | isoHeight [1..10]]

This is also the reason why the contour threshold is not implitly zero but an explicit parameter: if we used the family of functions \(f_h(x) = f(x)-h\) to calculate the iso lines at height \(h\), we would have to recreate the value table for each invocation.

Concrete example

Expand

Let’s draw some circles! The equation of a circle of radius \(r\) at point \(p\) is

\[ \left\{ x \; \big| \; \| x-p\| = r, \, x\in\mathbb R^2 \right\} \]

We can translate this directly into code like so (squaring the equation to save us a costly call to sqrt),

circle p = \x -> normSquare (x -. p)

and finding the contour lines at height \(r^2\) gives us our circles!

grid :: Grid
grid = Grid (Vec2 (-10) (-10), Vec2 10 10) (100, 100)

circleTrajectory :: Double -> [Vec2]
circleTrajectory =
    let iso = isoLines grid (circle zero)
    in \r -> head (iso (r^2)) -- NB head is safe here because each of our functions has exactly one iso line at a certain height

manyCircles :: [[Vec2]]
manyCircles = map circleTrajectory [1..9]

data Grid Source #

Specification of a discrete grid, used for sampling contour lines.

Subdivide the unit square with 50 squares (51 steps!) in x direction, and 30 (31 steps!) in y direction:

Grid (Vec2 0 0, Vec2 1 1) (50, 30)

Constructors

Grid 

Fields

Instances

Instances details
Show Grid Source # 
Instance details

Defined in Geometry.LookupTable.Lookup2

Methods

showsPrec :: Int -> Grid -> ShowS #

show :: Grid -> String #

showList :: [Grid] -> ShowS #

NFData Grid Source # 
Instance details

Defined in Geometry.LookupTable.Lookup2

Methods

rnf :: Grid -> () #

Eq Grid Source # 
Instance details

Defined in Geometry.LookupTable.Lookup2

Methods

(==) :: Grid -> Grid -> Bool #

(/=) :: Grid -> Grid -> Bool #

Ord Grid Source # 
Instance details

Defined in Geometry.LookupTable.Lookup2

Methods

compare :: Grid -> Grid -> Ordering #

(<) :: Grid -> Grid -> Bool #

(<=) :: Grid -> Grid -> Bool #

(>) :: Grid -> Grid -> Bool #

(>=) :: Grid -> Grid -> Bool #

max :: Grid -> Grid -> Grid #

min :: Grid -> Grid -> Grid #