

Title  Draw an Apollonian gasket (or Apollonian packing) in Visual Basic 6 
Description  This example shows how to draw an Apollonian gasket (or Apollonian packing) in Visual Basic 6. 
Keywords  mathematics, algorithms, graphics, Apollonian gasket, Apollonian packing, Apollonius' Problem, Apollonius, Apollonian circles, tangent cicles, geometry, example, example program, Windows Forms programming, Visual Basic 6, VB 6 
Categories  Algorithms, Graphics 


The example Find circles that are tangent to three given circles in Visual Basic 6 shows how to find up to eight circles that are tangent to three given circles. This example uses that method to build an Apollonian gasket.
(This is also called an Apollonian packing. If you think of each circle as cutting a hole in the enclosing circle so you get a lacelike figure, it's a gasket. If you think of filling the enclosing circle with other circles, it's a packing.)
The following FindApollonianPacking method controls the drawing and returns a Bitmap holding the packing.


' Find the Apollonian packing.
Private Sub FindApollonianPacking(ByVal pic As PictureBox, _
ByVal width As Integer)
Dim Radius As Single
Dim X As Single
Dim gasket_height As Single
Dim Y As Single
Dim circle0 As MyCircle
Dim circle1 As MyCircle
Dim circle2 As MyCircle
Dim big_circle As MyCircle
Dim level As Integer
pic.Cls
' Create the three central tangent circles.
Radius = width * 0.225
X = width \ 2
gasket_height = 2 * CSng(Radius + 2 * Radius / Sqr(3))
Y = (width  gasket_height) / 2 + Radius
Set circle0 = New MyCircle
circle0.X = X
circle0.Y = Y
circle0.Radius = Radius
X = X  Radius
Y = Y + CSng(Radius * Sqr(3))
Set circle1 = New MyCircle
circle1.X = X
circle1.Y = Y
circle1.Radius = Radius
X = X + 2 * Radius
Set circle2 = New MyCircle
circle2.X = X
circle2.Y = Y
circle2.Radius = Radius
' Draw the three central circles.
circle0.Draw pic, vbRed
circle1.Draw pic, vbRed
circle2.Draw pic, vbRed
' Find the circle that contains them all.
Set big_circle = FindApollonianCircle( _
circle0, circle1, circle2, 1, 1, 1)
big_circle.Draw pic, vbRed
' Set level to smaller values such as 3 to see partially
' drawn gaskets.
level = 10000
' Find the central circle.
FindCircleOutsideAll level, pic, circle0, circle1, _
circle2
' Find circles tangent to the big circle.
FindCircleOutsideTwo level, pic, circle0, circle1, _
big_circle
FindCircleOutsideTwo level, pic, circle1, circle2, _
big_circle
FindCircleOutsideTwo level, pic, circle2, circle0, _
big_circle
End Sub


This method starts by creating the three largest circles inside the enclosing circle. It does a little math to size the circles appropriately, arranges them so they are tangent, and then draws them.
Next the code calls the FindApollonianCircle method used by the previous example to find a circle tangent to the three large circles. It passes the parameters 1, 1, and 1 to find the tangent circle that contains all three of the big circles so the result is the enclosing circle. The program draws the enclosing circle.
The code then calls the FindCircleOutsideAll method to find and draw the small circle that sits between the three initial circles. It finishes by calling FindCircleOutsideTwo three times to find the circles that lie inside the enclosing circle but outside of two of the inner big circles.
The following code shows the FindCircleOutsideAll method.


' Draw a circle tangent to these three circles and that is
' outside all three.
Private Sub FindCircleOutsideAll(ByVal level As Integer, _
ByVal pic As PictureBox, ByVal circle0 As MyCircle, _
ByVal circle1 As MyCircle, ByVal circle2 As MyCircle)
Dim new_circle As MyCircle
Set new_circle = FindApollonianCircle(circle0, circle1, _
circle2, 1, 1, 1)
If (new_circle Is Nothing) Then Exit Sub
If (new_circle.Radius < 0.1) Then Exit Sub
new_circle.Draw pic, vbRed
level = level  1
If (level > 0) Then
FindCircleOutsideAll level, pic, circle0, circle1, _
new_circle
FindCircleOutsideAll level, pic, circle0, circle2, _
new_circle
FindCircleOutsideAll level, pic, circle1, circle2, _
new_circle
End If
End Sub


The FindCircleOutsideAll method finds a circle tangent to three other circles that does not contain any of the three. In this program that is the circle that lies between the three other circles. For example, the very center circle lies between the three large circles.
The code calls the FindApollonianCircle method used by the previous example program, passing it the parameters 1, 1, 1 to find the desired circle. If it finds such a circle, the code draws it.
The code then decrements the level parameter and if it is still greater than 0 the method calls itself recursively three times to find the circles between the new circle and the pairs of the original three circles. (Study the picture to see where those areas are.)
The following code shows the FindCircleOutsideTwo method.


' Draw a circle tangent to these three circles and that is
' outside two of them.
Private Sub FindCircleOutsideTwo(ByVal level As Integer, _
ByVal pic As PictureBox, ByVal circle0 As MyCircle, _
ByVal circle1 As MyCircle, ByVal circle_contains As _
MyCircle)
Dim new_circle As MyCircle
Set new_circle = FindApollonianCircle( _
circle0, circle1, circle_contains, 1, 1, 1)
If (new_circle Is Nothing) Then Exit Sub
If (new_circle.Radius < 0.1) Then Exit Sub
new_circle.Draw pic, vbRed
level = level  1
If (level > 0) Then
FindCircleOutsideTwo level, pic, new_circle, _
circle0, circle_contains
FindCircleOutsideTwo level, pic, new_circle, _
circle1, circle_contains
FindCircleOutsideAll level, pic, circle0, circle1, _
new_circle
End If
End Sub


This method finds a circle that is inside one circle and outside two others. For example, in the figure this method draws the mediumsized circle on the upper right that lies inside the enclosing circle and outside the two big circles.
The code calls the FindApollonianCircle method passing it the parameters 1, 1, and 1 to find the appropriate circle. Note that the order in which the code passes the circles to that method is important because the last circle is the one that should contain the new circle.
Next the code decrements the level parameter and if it is still greater than 0 the method calls itself recursively three times to find the circles in the areas it has just created. (Again study the picture to see where those areas are.)








