diff --git a/FieldTrip.cabal b/FieldTrip.cabal
--- a/FieldTrip.cabal
+++ b/FieldTrip.cabal
@@ -1,11 +1,11 @@
 Name:                FieldTrip
-Version:             0.2.1
+Version:             0.2.2
 Synopsis: 	     Functional 3D
 Category:            graphics
 Description:
   FieldTrip is a library for functional 3D geometry
   .
-  Please see the project wiki page: <http://haskell.org/haskellwiki/reactive>
+  Please see the project wiki page: <http://haskell.org/haskellwiki/FieldTrip>
   .
   The module documentation pages have links to colorized source code and
   to wiki pages where you can read and contribute user comments.  Enjoy!
diff --git a/examples/src/Perf.hs b/examples/src/Perf.hs
deleted file mode 100644
--- a/examples/src/Perf.hs
+++ /dev/null
@@ -1,175 +0,0 @@
-{-# LANGUAGE TypeOperators #-}
-{-# OPTIONS_GHC -Wall #-}
-----------------------------------------------------------------------
--- |
--- Module      :  Perf
--- Copyright   :  (c) Andy J Gill and Conal Elliott 2008
--- License     :  BSD3
--- 
--- Maintainer  :  conal@conal.net
--- Stability   :  experimental
--- 
--- Try get peformance better
-----------------------------------------------------------------------
-
--- module Test where
-
--- import Data.Monoid
--- import Control.Applicative
-
-import Graphics.Rendering.OpenGL (Color)
--- import Graphics.FieldTrip.Glut 
-
--- import Data.Derivative ((:>))
-
-import Graphics.FieldTrip.Misc
--- import Graphics.FieldTrip.Geometry2
-import Graphics.FieldTrip.Geometry3
--- import Graphics.FieldTrip.Transform
--- import Graphics.FieldTrip.Transform3
-import Graphics.FieldTrip.Vector2
-import Graphics.FieldTrip.Vector3
-import Graphics.FieldTrip.Color
-import Graphics.FieldTrip.Image
--- import Graphics.FieldTrip.Render
-
-import qualified Graphics.FieldTrip.ParamSurf as P
-import Graphics.FieldTrip.ParamSurf hiding (torus)
-
--- import Data.Behavior
--- import Data.Reactive
-
-import Data.VectorSpace
-import Data.MemoTrie
--- import System.Environment	
--- import Data.Cross
--- import Debug.Trace
-
-import Graphics.FieldTrip.Normal3
-import System.Time
-import Data.Derivative
-import Data.IORef
-import System.IO.Unsafe
-
-torusCrate :: Geometry3
-torusCrate = colorG blue $ surfG fun
-
-main :: IO ()
-main = do
-        () <- return () -- stops the rest from being a CAF
-
-	writeIORef counterVar 0
-
-	let fun2 :: Vector2 R -> VN3 R
-            fun2 v = vsurf fun v
-	let sz       = 49
-            numVerts = sqr (succ sz)
-
-	putStrLn ("Test: " ++ show numVerts ++ " vertices")
-
-	clock <- newClock
-        -- getClockTime >>= print
-
-	sequence_ [ p `seq` n `seq` return ()
-                  | x <- map (/sz) [0..sz]
-		  , y <- map (/sz) [0..sz]
-		  , let VN p n = fun2 (Vector2 x y) ]
-	-- getClockTime >>= print
-        t <- clock
-        putStrLn $ show t ++ " seconds.  " ++
-                   show (numVerts / t) ++ " vertices per second."
-
-        count <- readIORef counterVar
-
-	putStrLn $ "Count == " ++ show count
-        putStrLn $ "Count/vertex == " ++ show (fromIntegral count / numVerts)
-
--- A provider of relative time
-type Clock = IO R
-
-newClock :: IO Clock
-newClock = currRelTime `fmap` getClockTime
-
--- Get the current time in seconds, relative to a start 'ClockTime'.
-currRelTime :: ClockTime -> IO R
-currRelTime (TOD sec0 pico0) = fmap delta getClockTime
- where
-   delta (TOD sec pico) =
-     fromIntegral (sec-sec0) + 1.0e-12 * fromIntegral (pico-pico0)
-
-
-sqr :: Num a => a -> a
-sqr a = a * a
-
-fun :: Surf (Vector2 R :> R)
-fun v = 0 ^/ magnitude r1
-  where
-    r1 = unvector3D (normalV (vector3D (tt v)))
-
-tt :: Surf (Vector2 R :> R)
-tt = P.torus 1 (1/2)
-
-normalV :: Vector2 R :> Vector3 R -> Vector2 R :> Vector3 R
-normalV v = d (Left ()) `cross3` d (Right ())
-   where
-     d = untrie (derivative v)
-
-	-- vector3F :: Three (Vector2 R :> R) -> Vector2 R :> Vector3 R
-	-- vector3F (u,v,w) = liftA3 Vector3 u v w
-
-	-- unvector3F :: Vector2 R :> Vector3 R -> Three (Vector2 R :> R)
-	-- unvector3F d = (vector3x <$> d, vector3y <$> d, vector3z <$> d)
-
-
-cross3X :: (Vector2 R :> Vector3 R) -> (Vector2 R :> Vector3 R) -> Vector2 R :> Vector3 R
-cross3X = distrib cross3X'
-
--- when i replaced the recursive cross3X with (^+^), the cross3X per
--- vertex drops from 73 to 1.  but the running time stays about the same.
-
-cross3X' :: Vector3 R -> Vector3 R -> Vector3 R
-Vector3 ax ay az `cross3X'` Vector3 bx by bz = counter $
-	    Vector3 (ay * bz - az * by)
-	            (az * bx - ax * bz)
-	            (ax * by - ay * bx)
-
-
---	let v = P.torus 1 (1/2) xy
---	((fmap (\ v -> v ^+^ (0 *^ normal v)) tt)) xy
---             displace (P.torus 1 (1/2)) (\ (_,_) -> 0) -- (stretchH eggcrateH)
-
---tt = P.torus 1 (1/2)
---tt = \ (u,v) -> (u,v,u*v)
---tt = revolve (const (1,0) ^+^ (1/2) *^ liftA2 (,) cosU sinU)
-
-testH :: HeightField (Vector2 R :> R) -> Geometry3
-testH = surfG . hfSurf . stretchH
-
-testH' :: Color c => Image c -> HeightField (Vector2 R :> R) -> Geometry3
-testH' im = flip surfG' im . hfSurf . stretchH
-
-stretchH :: Fractional s => HeightField s -> HeightField s
-stretchH hf = (/ 5) . hf . (* 5)
-
-ptor :: Color c => Image c -> Geometry3
-ptor = surfG' (P.torus 1 (1/2))
-
-groovy :: ImageC
-groovy (s,t) =
-  rgba (sinU (3*s+5*t)) (cosU (5*t-3*s)) (sinU (3*s+5*t)) ((1+sinU (5*s*t) / 2))
-
-redTorus, greenCyl :: Geometry3
-redTorus = colorG red   $ torus 1 (1/2)
-greenCyl = colorG green $ cylinder (1/3) 3
-
-
-{-# NOINLINE counterVar #-}
-counterVar :: IORef Int
-counterVar = unsafePerformIO $ newIORef 0
-
-{-# NOINLINE counter #-}
-counter :: a -> a
-counter a = unsafePerformIO $ do
-		val <- readIORef counterVar
-		writeIORef counterVar $! succ val
-		return $ a
diff --git a/examples/src/Tablet.hs b/examples/src/Tablet.hs
deleted file mode 100644
--- a/examples/src/Tablet.hs
+++ /dev/null
@@ -1,105 +0,0 @@
-{-# OPTIONS_GHC -Wall #-}
-----------------------------------------------------------------------
--- |
--- Module      :  Tablet
--- Copyright   :  (c) Conal Elliott and Andy J Gill 2008
--- License     :  BSD3
--- 
--- Maintainer  :  conal@conal.net, andygill@ku.edu
--- Stability   :  experimental
--- 
--- Tablet shape with rounded corners
-----------------------------------------------------------------------
-
-module Tablet where
-
-import Data.Monoid
-
-import Graphics.FieldTrip.Misc
-import Graphics.FieldTrip.Vector3
-import Graphics.FieldTrip.Transform
-import Graphics.FieldTrip.Transform2
-import Graphics.FieldTrip.Geometry2
-import Graphics.FieldTrip.Geometry3
-
---import Graphics.FieldTrip.QParamSurf as Q
-
--- 2D rectangle with rounded corners, having given width, height, and
--- rounding radius.
-roundedRect :: R -> R -> R -> Geometry2
-roundedRect width height radius = right `sandwich2` center
-  -- Build out of left, center, right.
-  -- The sides sandwich the center to make the whole; and
-  -- the quarter-disks sandwich the edge strip to make the right side.
- where
-   -- Trimmed dimensions
-   width'  = width-2*radius
-   height' = height-2*radius
-   center = box2 width' height
-   -- Quarter-disk at origin, angle ranges from 0 to pi/2 (3pm to noon)
-   qdisk = uscale2 radius *% diskWedge (1/4)
-   ne = move2Y (height'/2) qdisk
-   se = move2Y (-height'/2) (rotate2 (-pi/2::Float) *% qdisk)
-   right = move2X (width'/2) $
-           ne `mappend` move2X (radius/2) (box2 radius height') `mappend` se
-
--- Sandwich @inside@ between @outside@ and a flipped version of @outside@
-sandwich2 :: Geometry2 -> Filter2
-outside `sandwich2` inside = andFlip2 outside `mappend` inside
-
-
-
--- 3D tablet shape, with flat top & bottom, using roundedRect.
--- Cylinders for the four corners.
-
-tablet1 :: R -> R -> R -> R -> Geometry3
-tablet1 width height depth radius = top `sandwichY` edging
- where
-   width'  = width-2*radius
-   height' = height-2*radius
-   top = move3Z (depth/2) $ flatG (roundedRect width height radius)
-   edging  = andFlip3 (zVector3::Vector3 Float) ell
-   ell = capped height' (width'/2) `mappend`
-         pivot3Z (capped width' (height'/2))
-   capped len dx = ( move3X (dx+radius) $
-                     pivot3Y $
-                     flatG (box2 depth len) )
-                   `mappend`
-                   ( move3 dx (len/2) 0 $
-                     cylinder radius depth )
-
--- Or with more rounding.
--- 3D tablet with half-cylinders for sides and quarter-sphere corners,
--- having given width, height, and depth.  Rounding radius is depth/2.
-tablet2 :: R -> R -> R -> Geometry3
-tablet2 width height depth = ell `sandwichZ` center
-  -- Build out of two ell shapes sandwiching a center box.  Each ell has
-  -- two cylinders and two spheres.  I can't yet make partial spheres or
-  -- cylinders, so I'll make full ones, which will be partly hidden (half
-  -- of each cylinder and 3/4 of each sphere).  Later, make the partial
-  -- versions, to reduce computing and rendering.
- where
-   radius   = depth/2
-   width'   = width-2*radius
-   height'  = height-2*radius
-   center   = box3 width' height' depth
-   right    = move3X (width'/2) $
-              move3Y (height'/2) (sphere radius) `sandwichX` rightCyl
-   ell      = move3Y (height'/2) topCyl `mappend` right
-   rightCyl = cyl xVector3 height'
-   topCyl   = cyl yVector3 width'
-   cyl :: Vector3 Float -> R -> Geometry3
-   cyl axis len = pivot3 axis $ cylinder radius len
-
-
----- utilities
-
--- Sandwich @inside@ between @outside@ and a flipped version of @outside@
-sandwich3 :: Vector3 Float -> Geometry3 -> Filter3
-sandwich3 axis outside inside = andFlip3 axis outside `mappend` inside
-
--- Specializations
-sandwichX, sandwichY, sandwichZ :: Geometry3 -> Filter3
-sandwichX = sandwich3 xVector3
-sandwichY = sandwich3 yVector3
-sandwichZ = sandwich3 zVector3
diff --git a/examples/src/Test.hs b/examples/src/Test.hs
deleted file mode 100644
--- a/examples/src/Test.hs
+++ /dev/null
@@ -1,175 +0,0 @@
-{-# LANGUAGE TypeOperators #-}
--- {-# OPTIONS_GHC -Wall #-}
-----------------------------------------------------------------------
--- |
--- Module      :  Test
--- Copyright   :  (c) Andy J Gill and Conal Elliott 2008
--- License     :  BSD3
--- 
--- Maintainer  :  conal@conal.net
--- Stability   :  experimental
--- 
--- Tablet shape with rounded corners
-----------------------------------------------------------------------
-
-module Main where
-
-import Data.Monoid
-import Control.Applicative
-
-import Graphics.Rendering.OpenGL (Color)
-import Graphics.FieldTrip.Glut 
-
-import Data.VectorSpace
-import Data.Derivative ((:>))
-
-import Graphics.FieldTrip.Misc
-import Graphics.FieldTrip.Geometry2
-import Graphics.FieldTrip.Geometry3
-import Graphics.FieldTrip.Transform
-import Graphics.FieldTrip.Transform3
-import Graphics.FieldTrip.Vector2
-import Graphics.FieldTrip.Vector3
-import Graphics.FieldTrip.Color
-import Graphics.FieldTrip.Material
-import Graphics.FieldTrip.Image
-import Graphics.FieldTrip.Render
-import qualified Graphics.FieldTrip.ParamSurf as P
-import Graphics.FieldTrip.ParamSurf hiding (torus)
-
-import Graphics.Formats
-
--- These next two aren't yet release openly.
-
--- import Graphics.Formats.Obj
--- import Codec.Image.DevIL
-
-import System.IO.Unsafe
-
--- import Data.Behavior
-import FRP.Reactive.Reactive
-
-import FRP.Reactive.Internal.Misc (Sink)
-
--- import Tablet
-
-main :: IO ()
-main =
-  do -- ilInit
-     anim3 $ spinningG $
-         -- flatG ubox2
-         -- uscale3 (3::R) *% (sphere 0.3 `mappend` flatG ubox2)
-         -- cube
-         -- flatG $ uscale2 (0.5::R) *% diskWedge (1/3)
-         -- flatG $ roundedRect 2 3 (1/2)
-         -- pivot3 (xVector3::Vector3 R) $ cylinder (1/2) 2
-         -- tablet1 2 3 (1/2) (1/4)
-         -- tablet2 2 3 (1/2)
-         -- cone 1 1
-         -- redTorus `mappend` greenCyl
-         torusPair
-         -- ptor (rings . (50 *^))
-         -- ptor (checker . (50 *^))
-         -- ptor groovy
-         -- testH' groovy eggcrateH
-         -- testH rippleH
-         -- when testing the next two, increase gcErr (below) to 0.05
-         -- torusCrate
-         -- torusCrate'
-         -- loadObj "Astin DB9.obj"
-
--- loadObj :: String -> Geometry3
--- loadObj x =
---   renderableG obj
---   where
---      obj = unsafePerformIO
---               $ objFromFile ("examples/" ++ x) ["examples/"]
-
-plasmat :: Col -> Filter3
-plasmat col = materialG (plastic col)
-
-torusCrate, torusCrate' :: Geometry3
-torusCrate = plasmat yellow $ surfG $
-             displace (P.torus 1 (1/2)) (stretchH eggcrateH)
-
-torusCrate' = flip surfG' groovy $
-              displace (P.torus 1 (1/2)) (stretchH eggcrateH)
-
-testH :: HeightField (Vector2 R :> R) -> Geometry3
-testH = surfG . hfSurf . stretchH
-
-testH' :: Color c => Image c -> HeightField (Vector2 R :> R) -> Geometry3
-testH' im = flip surfG' im . hfSurf . stretchH
-
-stretchH :: Fractional s => HeightField s -> HeightField s
-stretchH hf = (/ 10) . hf . (* 10)
-
-ptor :: Color c => Image c -> Geometry3
-ptor = surfG' (P.torus 1 (1/2))
-
-groovy :: ImageC
-groovy (s,t) =
-  rgba (sinU (3*s+5*t)) (cosU (5*t-3*s)) (sinU (3*s+5*t)) ((1+sinU (5*s*t) / 2))
-
-redTorus, greenCyl :: Geometry3
-redTorus = plasmat red   $ torus 1 (1/2)
-greenCyl = plasmat green $ cylinder (1/3) 3
-
-torusPair :: Geometry3
-torusPair = f red (1/2) `mappend` pivot3X (f green (-1/2))
- where
-   tor = torus 1 (2/5)
-   f :: Col -> R -> Geometry3
-   f col dx = plasmat col (move3X dx tor)
-
-spinningG :: Geometry3 -> Anim Geometry3
-spinningG g env = liftA2 (*%) (spinning env) (pure g)
-
-spinning :: Anim (Transform3 Double)
-spinning env = (f . (*1)) <$> timeR env
- where
-   f t = translate3 (Vector3 (0::Double) 0 (3*sin (-t/5)))
-         `mappend` rotate3 t (Vector3 0.1 0.2 0.3)
-         `mappend` scale3 0.2 0.2 0.2
-
-{-
-
--- This reads mouse clicks, and 
-withClick :: GlutEvents -> Behavior Double
-withClick events = timeB
-{-
-fmap (\ (a,b) -> b)
-		 $ snapshot mouseEvents timeB
--}
-  where
-	mouseEvents :: Event Bool
-	mouseEvents = fmap (\ (_,x,_,_) ->
-				       case x of
-					 Up -> False
-					 Down -> True)
-		   $ filterMP (\ (key,state,mods,pos) ->
-				    case (key,state) of
-				      (MouseButton _,Down) -> True
-				      _ -> False) 
-			       (keyboardMouseEvent events)
-
--}
-
-view :: Filter3
-view = move3Z (-3 :: R)
-
-animate :: Sink a -> Sink (Anim a)
-animate f anim = runWithGlut ((fmap.fmap) f anim)
-
-anim2 :: Sink (Anim Geometry2)
-anim2 = animate render2
-
-anim3 :: Sink (Anim Geometry3)
-anim3 = animate (renderWith3 gc . view)
- where
-   gc = defaultGC { gcErr = 0.01 }
-
-
--- Later:
-
--- type Anim a = GlutEvents -> Behavior a
diff --git a/src/Graphics/FieldTrip.hs b/src/Graphics/FieldTrip.hs
--- a/src/Graphics/FieldTrip.hs
+++ b/src/Graphics/FieldTrip.hs
@@ -42,7 +42,7 @@
 import Graphics.FieldTrip.Color
 import Graphics.FieldTrip.Material
 import Graphics.FieldTrip.Render
-import Graphics.FieldTrip.ParamSurf hiding (frustrum,torus)
+import Graphics.FieldTrip.ParamSurf hiding (frustum,torus)
 import Graphics.FieldTrip.Image
 import Graphics.FieldTrip.Geometry2
 import Graphics.FieldTrip.Geometry3
diff --git a/src/Graphics/FieldTrip/Geometry3.hs b/src/Graphics/FieldTrip/Geometry3.hs
--- a/src/Graphics/FieldTrip/Geometry3.hs
+++ b/src/Graphics/FieldTrip/Geometry3.hs
@@ -22,7 +22,7 @@
   , renderWith3, render3
   , normalArrowG
   , cube, box3
-  , sphere, usphere, frustrum, cone, cylinder, torus
+  , sphere, usphere, frustum, cone, cylinder, torus
   , surfG, surfG'
   -- * Geometry filters
   , Filter3, move3, move3X, move3Y, move3Z, pivot3, andFlip3
@@ -37,7 +37,7 @@
 import Data.Monoid
 import Control.Applicative
 
-import Graphics.Rendering.OpenGL hiding (normal)
+import Graphics.Rendering.OpenGL hiding (normal,frustum)
 import qualified Graphics.Rendering.OpenGL as G
 
 -- TypeCompose
@@ -67,7 +67,7 @@
 -- for parametric surfaces
 import Data.Derivative ((:>),pureD,idD,powVal)
 import qualified Graphics.FieldTrip.ParamSurf as P
-import Graphics.FieldTrip.ParamSurf hiding (frustrum,torus)
+import Graphics.FieldTrip.ParamSurf hiding (frustum,torus)
 
 -- | 3D geometry
 data Geometry3
@@ -215,21 +215,21 @@
 sphere :: R -> Geometry3
 sphere r = uscale3 r *% usphere
 
--- | Frustrum of a cone, with given base radius, top radius, and height,
+-- | Frustum of a cone, with given base radius, top radius, and height,
 -- centered at origin.
-frustrum :: R -> R -> R -> Geometry3
-frustrum baseR topR h =
-  surfG (P.frustrum (pureD baseR) (pureD topR) (pureD h))
+frustum :: R -> R -> R -> Geometry3
+frustum baseR topR h =
+  surfG (P.frustum (pureD baseR) (pureD topR) (pureD h))
 
 -- | Cone with given base radius and height, and height,
 -- centered at origin..
 cone :: R -> R -> Geometry3
-cone r h = frustrum r 0 h
+cone r h = frustum r 0 h
 
 -- | Cylinder with given radius and height, centered at origin, and height,
 -- centered at origin..
 cylinder :: R -> R -> Geometry3
-cylinder r h = frustrum r r h
+cylinder r h = frustum r r h
 
 -- | Torus with given radii for the sweep and the swept circle
 torus :: R -> R -> Geometry3
diff --git a/src/Graphics/FieldTrip/ParamSurf.hs b/src/Graphics/FieldTrip/ParamSurf.hs
--- a/src/Graphics/FieldTrip/ParamSurf.hs
+++ b/src/Graphics/FieldTrip/ParamSurf.hs
@@ -90,9 +90,9 @@
 sphere2 = profile circle semiCircle
 sphere3 = profile semiCircle circle
 
--- | Frustrum, given base & cap radii and height.
-frustrum :: (Floating s, VectorSpace s, Scalar s ~ s) => s -> s -> s -> Surf s
-frustrum baseR topR h = profile circle rad
+-- | Frustum, given base & cap radii and height.
+frustum :: (Floating s, VectorSpace s, Scalar s ~ s) => s -> s -> s -> Surf s
+frustum baseR topR h = profile circle rad
  where
    rad t = (lerp baseR topR (t + 1/2), h*t)
 
diff --git a/wikipage.tw b/wikipage.tw
--- a/wikipage.tw
+++ b/wikipage.tw
@@ -1,13 +1,17 @@
-[[Category:Graphics]]	 
+[[Category:Graphics]]
+[[Category:3D]]
 [[Category:Packages]]
 
 == Abstract ==
 
+[[Image:Torus-pair-d-shadowed.png|right|thumb|300px|Torus pair modeled and rendered in FieldTrip]]
 '''FieldTrip''' is a library for functional 3D graphics, intended for building static, animated, and interactive 3D geometry, efficient enough for real-time synthesis and display.
 Our first renderer uses OpenGL, with the usual visual limitations.
 Since FieldTrip is functional, it is about ''being'' rather than ''doing''.
 One describes what models are, not how to render them.
 
+FieldTrip is just a toy / early release at this point, to show what's going on and see who's interested in collaborating on developing it further.
+
 Besides this wiki page, here are more ways to find out about and get involved with FieldTrip:
 * Join the [http://www.haskell.org/mailman/listinfo/FieldTrip FieldTrip mailing list].
 * Peruse [http://code.haskell.org/FieldTrip/doc/html/ the library documentation].
@@ -25,7 +29,7 @@
 : 3D geometry.  These values can be spatially transformed in space (affinely: scale, rotate, translate) and combined (union).
 
 ; <hask>Surf a = (a,a) -> (a,a,a)</hask>
-: Parametric surfaces, i.e., mappings from 2D to 3D.  Normals are constructed automatically and exactly via derivatives, thanks to the [[vector-space]] library.  These normals are used for shading.  For simplicity and composability, ''surfaces are curved'', not faceted.  Surface ''rendering'' tessellates adaptively, caching tessellations in an efficient, infinite data structure for reuse.  The mechanism for choosing tessellation is a very primitive placeholder.  FieldTrip provides some basic shapes of surfaces (spheres, torus, cubes, etc) and many functions for manipulating surfaces,  colors, etc.
+: Parametric surfaces, i.e., mappings from 2D to 3D.  Normals are constructed automatically and exactly via derivatives, thanks to the [[vector-space]] library.  These normals are used for shading.  For simplicity and composability, ''surfaces are curved'', not faceted.  Surface ''rendering'' tessellates adaptively, caching tessellations in an efficient, infinite data structure for reuse.  The mechanism for choosing tessellation is a very primitive placeholder.  FieldTrip provides some basic shapes of surfaces (spheres, torus, cubes, etc) and many functions for manipulating surfaces, colors, etc.
 
 ; <hask>Geometry2</hask>
 : 2D geometry.  There's a function (<hask>flatG</hask>) to embed 2D into 3D.
@@ -33,9 +37,72 @@
 ; <hask>Image o = (R,R) -> o</hask>
 : A primitive placeholder for functional imagery in the spirit of [http://conal.net/Pan Pan].  The intention is to use this type or something like it for texture mapping.  Much design and implementation work to be done.
 
+== Example ==
+
+The code for the static torus pair shown above:
+<haskell>
+torusPair :: Geometry3
+torusPair = f red (1/2) `mappend` pivot3X (f green (-1/2))
+ where
+   tor = torus 1 (2/5)
+   f :: Col -> R -> Geometry3
+   f col dx = plasmat col (move3X dx tor)
+</haskell>
+where <hask>pivot3X</hask> and <hask>move3X</hask> are simple helper functions for 3D transformation, and <hask>plasmat</hask> applies a color with a plastic look (defined in <code>Test.hs</code>).
+
+The <code>[http://code.haskell.org/FieldTrip/doc/html/Graphics-FieldTrip-ParamSurf.html#v%3Atorus torus]</code> function used here is a simple wrapper around a parametric surface defined as follows:
+<haskell>
+-- | Torus, given radius of sweep circle and cross section
+torus :: (Floating s, VectorSpace s, Scalar s ~ s) => s -> s -> Surf s
+torus sr cr = revolve (const (sr,0) ^+^ cr *^ circle)
+</haskell>
+where <hask>revolve</hask> and <hask>circle</hask> are defined in <code>[http://code.haskell.org/FieldTrip/doc/html/Graphics-FieldTrip-ParamSurf.html Graphics.FieldTrip.ParamSurf]</code>, along with other tools for shape generation.
+
+The trick to turning this polymorphic <hask>torus</hask> function into a <hask>Geometry3</hask> is to use a derivative tower (from [[vector-space]]) for the type parameter <hask>s</hask>.
+<haskell>
+surfG :: Surf (Vector2 R :> R) -> Geometry3
+
+torus :: R -> R -> Geometry3
+torus sr cr = surfG (P.torus (pureD sr) (pureD cr))
+</haskell>
+
+''[fill in more examples]''
+
 == FieldTrip meets Reactive ==
 
 FieldTrip contains no support for animation, because we intend it to be used with the [[Reactive]] functional reactive programming ([[FRP]]) library (and possibly other animation frameworks).
 By design, FieldTrip is completely orthogonal to any formulation or implementation of FRP.
 
 The [[reactive-fieldtrip]] project connects [[Reactive]] and FieldTrip.
+
+The picture above comes from an animation in [[reactive-fieldtrip]].
+Load <code>src/Test.hs</code>, as follows:
+<pre>
+    ~/Haskell$ cd reactive-fieldtrip/src
+    ~/Haskell/reactive-fieldtrip/src$ ghci
+    GHCi, version 6.10.1: http://www.haskell.org/ghc/  :? for help
+    Loading package ghc-prim ... linking ... done.
+    Loading package integer ... linking ... done.
+    Loading package base ... linking ... done.
+    Prelude> :l Test
+    :l Test
+    [1 of 2] Compiling FRP.Reactive.FieldTrip.Adapter ( FRP/Reactive/FieldTrip/Adapter.hs, interpreted )
+    [2 of 2] Compiling Test             ( Test.hs, interpreted )
+    Ok, modules loaded: FRP.Reactive.FieldTrip.Adapter, Test.
+</pre>
+Then run the example:
+<pre>
+    *Test> anim3 (spinningG torusPair)
+    Loading package OpenGL-2.2.1.1 ... linking ... done.
+    Loading package syb ... linking ... done.
+    Loading package base-3.0.3.0 ... linking ... done.
+    [...]
+    Loading package reactive-0.9.0 ... linking ... done.
+    Loading package FieldTrip-0.2.2 ... linking ... done.
+    Loading package reactive-glut-0.0.5 ... linking ... done.
+</pre>
+
+== Some videos ==
+
+* [http://www.youtube.com/watch?v=ulPsJzUCQi8 Texture-mapped Earth.]
+* [http://www.youtube.com/watch?v=WNB5V9Z7Obc The torus demo running in GHCi.]
