Copyright  (c) 2011 Brent Yorgey 

License  BSDstyle (see LICENSE) 
Maintainer  byorgey@cis.upenn.edu 
Safe Haskell  None 
Language  Haskell2010 
Generation of Apollonian gaskets. Any three mutually tangent circles uniquely determine exactly two others which are mutually tangent to all three. This process can be repeated, generating a fractal circle packing.
See J. Lagarias, C. Mallows, and A. Wilks, "Beyond the Descartes circle theorem", Amer. Math. Monthly 109 (2002), 338361. http://arxiv.org/abs/math/0101066.
A few examples:
import Diagrams.TwoD.Apollonian apollonian1 = apollonianGasket 0.01 2 2 2
import Diagrams.TwoD.Apollonian apollonian2 = apollonianGasket 0.01 2 3 3
import Diagrams.TwoD.Apollonian apollonian3 = apollonianGasket 0.01 2 4 7
 data Circle n = Circle {}
 mkCircle :: Fractional n => n > P2 n > Circle n
 center :: Fractional n => Circle n > P2 n
 radius :: Fractional n => Circle n > n
 descartes :: Floating n => [n] > [n]
 other :: Num n => [n] > n > n
 initialConfig :: RealFloat n => n > n > n > [Circle n]
 apollonian :: RealFloat n => n > [Circle n] > [Circle n]
 drawCircle :: (Renderable (Path V2 n) b, TypeableFloat n) => n > Circle n > QDiagram b V2 n Any
 drawGasket :: (Renderable (Path V2 n) b, TypeableFloat n) => [Circle n] > QDiagram b V2 n Any
 apollonianGasket :: (Renderable (Path V2 n) b, TypeableFloat n) => n > n > n > n > QDiagram b V2 n Any
Circles
Representation for circles that lets us quickly compute an Apollonian gasket.
Circle  

Eq n => Eq (Circle n) Source  
RealFloat n => Floating (Circle n) Source  The 
RealFloat n => Fractional (Circle n) Source  
RealFloat n => Num (Circle n) Source  
Show n => Show (Circle n) Source 
:: Fractional n  
=> n  signed radius 
> P2 n  center 
> Circle n 
Create a Circle
given a signed radius and a location for its center.
center :: Fractional n => Circle n > P2 n Source
Get the center of a circle.
radius :: Fractional n => Circle n > n Source
Get the (unsigned) radius of a circle.
Descartes' Theorem
descartes :: Floating n => [n] > [n] Source
Descartes' Theorem states that if b1
, b2
, b3
and b4
are
the bends of four mutually tangent circles, then
b1^2 + b2^2 + b3^2 + b4^2 = 1/2 * (b1 + b2 + b3 + b4)^2.
Surprisingly, if we replace each of the bi
with the product
of bi
and the center of the corresponding circle (represented
as a complex number), the equation continues to hold! (See the
paper referenced at the top of the module.)
descartes [b1,b2,b3]
solves for b4
, returning both solutions.
Notably, descartes
works for any instance of Floating
, which
includes both Double
(for bends), Complex Double
(for
bend/center product), and Circle
(for both at once).
other :: Num n => [n] > n > n Source
If we have four mutually tangent circles we can choose one of
them to replace; the remaining three determine exactly one other
circle which is mutually tangent. However, in this situation
there is no need to apply descartes
again, since the two
solutions b4
and b4'
satisfy
b4 + b4' = 2 * (b1 + b2 + b3)
Hence, to replace b4
with its dual, we need only sum the other
three, multiply by two, and subtract b4
. Again, this works for
bends as well as bend/center products.
initialConfig :: RealFloat n => n > n > n > [Circle n] Source
Generate an initial configuration of four mutually tangent circles, given just the signed bends of three of them.
Apollonian gasket generation
apollonian :: RealFloat n => n > [Circle n] > [Circle n] Source
Given a threshold radius and a list of four mutually tangent circles, generate the Apollonian gasket containing those circles. Stop the recursion when encountering a circle with an (unsigned) radius smaller than the threshold.
Diagram generation
drawCircle :: (Renderable (Path V2 n) b, TypeableFloat n) => n > Circle n > QDiagram b V2 n Any Source
Draw a circle.
drawGasket :: (Renderable (Path V2 n) b, TypeableFloat n) => [Circle n] > QDiagram b V2 n Any Source
Draw a generated gasket, using a line width 0.003 times the radius of the largest circle.
apollonianGasket :: (Renderable (Path V2 n) b, TypeableFloat n) => n > n > n > n > QDiagram b V2 n Any Source
Draw an Apollonian gasket: the first argument is the threshold; the recursion will stop upon reaching circles with radii less than it. The next three arguments are bends of three circles.