I’m guessing most of you already know what the graphics.curveTo function is. As the name suggests, it allows you to draw a curved line that starts at a certain point, bends towards a control point, and ends in an anchor point. The starting point of the curve can be defined in three ways:
After leaving the starting point, the curve will work its way to the Control point, and then curve to the Anchor point. That’s basically what curveTo() does.
So why would you draw a circle with the curveTo function when you can just use drawCircle ? One answer to this question is that it’s just fun to experiment with these things in flash, another answer is that when you dynamically draw a circle using this method, you can animate the different points that make up the circle and create even weirder shapes.
First thing we have to do is define all our Anchor points. Since we are drawing a circle, it would be helpful if the anchor points were nicely aligned in a circular fashion. One way to align pretty much everything in a circular order is working with sine and cosine, but right now I would like to try this another way, namely using the Point.polar() method. (no worries, we’ll be needing our trigonometric friends later on).
The polar() function works with polar coordinates, as opposed to cartesian coordinates that are standard in flash. The main idea behind the Polar coordinate system is that instead of working with an X and Y position to define a point, you work with an angle and a distance. The distance tells you how far this point is removed from the Pole (the fixed point in the system) and the angle tells you the angle of the point relative to a horizontal line going through the Pole.
So, if you want to draw a 100 points that are all on the edge of a perfect circle with radius 10, the polar coordinates for the first five points will be:

the Point.polar() method has 2 parameters, the first being the distance to the Pole, the second being the angle (in radians). The method then returns a Point object with the corresponding cartesian coordinates, and this allows you to draw this point on the screen in Flash. so, drawing all of our points (in this case a circle with radius 1) will go as follows:
this.graphics.beginFill(0); for (var i:int = 0; i < numberOfPoints; i++) { var p:Point = Point.polar(10,2*Math.PI * i/numberOfPoints); this.graphics.drawCircle(p.x,p.y,1); } this.graphics.endFill();
Now that I’ve made it clear how to draw the Anchor points in a circular method, all that is left is drawing the Control points. The Control Points will make sure that the curves between the anchor points form a nice circle. We’ll use some trigonometry from back in the high school days to find their coordinates. Because we will also use the Point.polar() method, all we need to do to find the coordinates, is the distance from the Control Points to the center. We can then re-use the for-loop above, with the adjusted distance to the Pole.

We can establish that the COS(delta/2) = r / |AB|. Thanks to this, we can calculate |AB|. the line AB is the angle bisector of Delta (meaning AB splits the angle Delta in 2 evenly divided parts). Point B is where the 2 Perpendicular lines meet with each other AND with the bisector -We are not going into specifics as to why this is, but feel free to prove this yourself
.
This leaves us with |AB|, the distance from the center of our circle to every Control Point. All that we need to do now is plot these points next to each other and draw Curves through them. Take a look at the following code to see what you need to draw a Circle with 10 Control Points and be amazed when you see how fluid the circle appears.
public class APC extends MovieClip { private var ControlPoints:Array = []; private var AttachPoints:Array = []; private var diameter:int = 100; private var Points:int = 10; public function APC() { var xx:int = stage.stageWidth/2; var yy:int = stage.stageHeight / 2; var outerDiameter:Number = diameter / Math.cos(Math.PI / Points); for (var i:int = 0; i < Points; i++) { var Ap:Point = Point.polar(diameter, i * 2 * Math.PI / Points); var Cp:Point = Point.polar(outerDiameter, i * 2 * Math.PI / Points + (Math.PI / Points )); Ap.x += xx; Ap.y += yy; Cp.x += xx; Cp.y += yy; AttachPoints.push(Ap); ControlPoints.push(Cp); } drawStuff(); } private function drawStuff():void { this.graphics.beginFill(0); this.graphics.moveTo(AttachPoints[0].x, AttachPoints[0].y); for (var i:int = 0; i < Points-1; i++) { this.graphics.curveTo(ControlPoints[i].x, ControlPoints[i].y, AttachPoints[i+1].x, AttachPoints[i+1].y); } this.graphics.curveTo(ControlPoints[Points-1].x, ControlPoints[Points-1].y, AttachPoints[0].x, AttachPoints[0].y); this.graphics.endFill(); } }
And to wrap things up, have a look at all the cool stuff you can do once you start tweening these points… Go forth and experiment !
Like this post ? Follow me on Twitter !
One thought on “drawing a perfect circle with the curveTo() function”