The intersection of two circles, generates a straight line, but if we change the relative position of the circles, the intersections can be used to create this:

Click here to start the example. ( Requires Flash )

First of all, lets check some simple maths.

Lets calculate the distance d between the center of the circles.

d = ||P1 - P0||

There are no solutions if the circles are separate, ( d > r0 + r1 ) or if one circle is contained within the other ( d < |r0 - r1| ).

If d = 0 and r0 = r1 then the circles are coincident and there are an infinite number of solutions, but we will forget about this case.

Taking a look the triangles P0P2P3 and P1P2P3 we can write

a2 + h2 = r02 and b2 + h2 = r12

Using d = a + b and solving for a,

a = ( r02 - r12 + d2 ) / 2d

substituting a into the first equation, h2 = r02 - a2

P2 = P0 + a ( P1 - P0 ) / d

If we calculate, P3 = (x3,y3) in terms of P0 = (x0,y0), P1 = (x1,y1) and P2 = (x2,y2), we get:

x3 = x2 +/- h ( y1 - y0 ) / d
y3 = y2 -/+ h ( x1 - x0 ) / d

If we draw a lot of circles, and then move then randomly, we can calculate the intersection of each circle with all the others, and for each circle intersection, we can draw a line between the two intersection dots.

The main code for this demo can be reduce to this:

circle = _lastCircle;

while(circle)
   {
   // move circle
   circle.x += circle.vcx;
   circle.y += circle.vcy;
   
   // check intersection with previous circles
   circle2 = circle.prev;
   
   while(circle2)
      {
      var dx:Number   = circle2.x - circle.x;
      var dy:Number   = circle2.y - circle.y;
      var d:Number    = SQRT ( dx*dx + dy*dy );
      var dd:Number   = d*d;

      // intersection test
      if (d < ( circle2.r + circle.r ) )
         {
         // complete containment test
         var ro:Number = circle2.r - circle.r;
         
         if ( d > ( ro < 0 ? -ro : ro ) )
            {
            // find solutions
            var a:Number    = (circle.rr-circle2.r*circle2.r+dd)/(2*dd);
            
            var x1:Number   = circle2.x - circle.x;
            var y1:Number   = circle2.y - circle.y;
            var sq:Number   = SQRT( circle.rr/dd - a*a );
            
            var p2x:Number   = circle.x + a*x1;
            var p2y:Number   = circle.y + a*y1;
            
            var hx:Number   = x1*sq;
            var hy:Number   = y1*sq;
            
            var p3ax:Number   = p2x + hy;
            var p3ay:Number   = p2y - hx;
            var p3bx:Number   = p2x - hy;
            var p3by:Number   = p2y + hx;
            
            // draw linear intersection
            circle.graphics.lineStyle( 1 , circle.color , 1 );
            circle.graphics.moveTo( p3ax-circle.x , p3ay-circle.y );
            circle.graphics.lineTo( p3bx-circle.x , p3by-circle.y );

            // drawing BUFFER
            CANVAS.graphics.lineStyle(0 , circle.color , .11 );
            CANVAS.graphics.moveTo( p3ax , p3ay );
            CANVAS.graphics.lineTo( p3bx , p3by );
            }
         }

      circle2 = circle2.prev;
      }

   circle = circle.prev;
   }

This will create the canvas that we have in this demo.



Download: Circle intersections source code (AS3)