Draws 2 circles(c0, c1), finds their intersections, chooses the first intersection,
draws a sligthly smaller circle with center at the intersection, repeat until the radius is very small
Draws some of the lines and tangents that emerges by the calculations of finding the intersection
/**
* Copyright Ricki_G ( http://wonderfl.net/user/Ricki_G )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/5XkQ
*/
package
{
import flash.display.Graphics;
import flash.display.Sprite;
import flash.geom.Point;
[SWF( width="512", height = "512", backgroundColor = "0x222222", frameRate = "120" )]
/**
* Draws 2 circles(c0, c1), finds their intersections, chooses the first intersection,
* draws a sligthly smaller circle with center at the intersection, repeat until the radius is very small
* Draws some of the lines and tangents that emerges by the calculations of finding the intersection
*
**/
public class CircleCircles extends Sprite
{
private var _circles:Vector.<Circle>;
private var _radius:Number = 128.0;
public function CircleCircles()
{
_circles = new Vector.<Circle>();
var g:Graphics = graphics;
g.lineStyle(0, 0xFFFFFF, 0.4)
//get started by drawing two circles which intersection will be used to iterate upon
var r:Number = Math.random() * Math.PI * 2;
var c0:Circle = new Circle(100, 256, _radius);
var c1:Circle = new Circle(320, 256, _radius);
_radius = 256.0;
var intersec:Object;
_circles.push( c0, c1 );
//the alpha used
var a:Number = 0.4;
while(_radius > 60)
{
//an interesect object containing the points and values of interest
//calculated for the two previous circles pushed to the vector
intersec = intersection( _circles[_circles.length - 2], _circles[_circles.length - 1] );
//decrease the radius a bit
_radius *= 0.9;
c0 = new Circle( intersec.x0, intersec.y0, _radius );
//draws the circles
g.lineStyle(0, 0xFF6600, a);
g.drawCircle( c0.x, c0.y, c0.radius );
//marks the intersection with a red circle
g.lineStyle(0, 0xFF0000, 1);
g.drawCircle(intersec.x0, intersec.y0, 2);
//there is always two intersections, this draws a line between them
g.moveTo(intersec.x1, intersec.y1);
g.lineStyle(0, 0x00FF00, a);
g.lineTo(c0.x, c0.y);
//draws a magenta line from an intersection to the center between two intersections
g.lineStyle(0, 0xFF00FF, a);
g.lineTo(intersec.x2, intersec.y2);
_circles.push( c0);
}
}
/**
* Takes to circle objects, calculates the intersection between them.
* @param c0 - a circle object
* @param c1 - a circle object
* @return - an object containing all intersections
*
*/
private function intersection(c0:Circle, c1:Circle):Object
{
var _h:Number; //height from common center line to intersection
var _a:Number; //length from circle0 center to
var _d:Number; //distance between centers
var _dx:Number; //distance at x axis
var _dy:Number; //distance at y axis
var _rx:Number; //radius x value
var _ry:Number; //radius y value
var _p0:Point = new Point(); //first intersection
var _p1:Point = new Point(); //second intersection
var _p2:Point = new Point(); //intermediate value
var intersects:Object = new Object();
_p0.x = c0.x;
_p0.y = c0.y;
_p1.x = c1.x;
_p1.y = c1.y;
_dx = c1.x - c0.x;
_dy = c1.y - c0.y;
_d = Math.sqrt(Math.pow(( _dx ), 2) + Math.pow(( _dy ), 2));
_a = (( Math.pow( c0.radius, 2 ) - Math.pow( c1.radius, 2) + Math.pow( _d, 2)) / ( _d * 2 ));
_p2.x = c0.x + (_dx * _a/_d);
_p2.y = c0.y + (_dy * _a/_d);
_h = Math.sqrt( (Math.pow( c0.radius, 2) - Math.pow( _a, 2) ) );
_rx = -_dy * ( _h / _d);
_ry = _dx * ( _h / _d);
//fill up the object with all values calculated
intersects.x0 =_p2.x + _rx;
intersects.y0 = _p2.y + _ry;
intersects.x1 = _p2.x - _rx;
intersects.y1 = _p2.y - _ry;
intersects.rx = _rx;
intersects.ry = _ry;
intersects.x2 = _p2.x;
intersects.y2 = _p2.y;
return intersects;
}
}
}
//simple helper class to contain the circles data
class Circle
{
private var _x:Number;
private var _y:Number;
private var _radius:Number;
public function Circle(xPos:Number, yPos:Number, radii:Number)
{
_x = xPos;
_y = yPos;
_radius = radii;
}
public function get radius():Number
{
return _radius;
}
public function get x():Number
{
return _x;
}
public function get y():Number
{
return _y;
}
}