Draw an Arc with ActionScript
Drawing an arc (a segment of a circle’s circumference) is very similar to drawing a complete circle. Just like drawing a circle, drawing an arc requires you to specify the center, the radius, and the number of steps to take from the first point to the last. But drawing an arc also requires additional information such as the angle of the first point on the arc, the direction (clockwise or counter-clockwise) to travel around the circle’s circumference, and the angle of the last point on the arc.
So the arguments in our “drawArc” function might look something like this:
function drawArc (centerX, centerY, radius, startAngle, endAngle, direction, steps){
//
That isn’t too bad, but it could be better. The “endAngle” and the “direction” arguments could be combined into one “arcAngle” argument. That way we can say, “Start at an angle of 45 degrees then sweep counter-clockwise 90 degrees” rather than, “Start at an angle of 45 degrees then go counter-clockwise until you get to 315 degrees.” Our modified arguments would look like this:
function drawArc (centerX, centerY, radius, startAngle, arcAngle, steps){
//
If you read my previous article you probably understand that drawing a circle involves moving through a series of points and that each point is described by its angle from center. The angle can be described using degrees, radians or a ratio. I prefer using a ratio from 0 to 1 as it’s simple and easily converted to any other unit of measurement such as degrees or radians.
Example: A quarter of a full rotation can be represented in any number of ways: 90 degrees, 25%, 1/2 Math.PI radians, or as .25 when expressed as a ratio from 0 to 1. Using a ratio has the benefit of abstracting your data and removing “arbitrary” numbers such as 360, 100, 2*Math.PI, 2 to the 64th power, etc. To convert from a ratio to any other unit of measure, simply multiply the ratio times the number of units in one full rotation.
Now that we have our arguments all set up and know how they’ll be formatted, it’s time to move on to writing the actual guts of the code which will be responsible for drawing the arc. Using the knowledge gained in the previous circle article you should understand how to plot any point on a circle’s circumference as long as you know its angle from center. Since we can draw any point at a given angle and we know the arguments we’ll be using, writing the “drawArc” function is as easy as determining the angle of each point on the arc and then plotting its position.
// Angles are expressed as a number between 0 and 1. .25 = 90 degrees.
// If you prefer using degrees, write 90 degrees like so "90/360".
function drawArc(centerX, centerY, radius, startAngle, arcAngle, steps){
//
// For convenience, store the number of radians in a full circle.
var twoPI = 2 * Math.PI;
//
// To determine the size of the angle between each point on the
// arc, divide the overall angle by the total number of points.
var angleStep = arcAngle/steps;
//
// Determine coordinates of first point using basic circle math.
var xx = centerX + Math.cos(startAngle * twoPI) * radius;
var yy = centerY + Math.sin(startAngle * twoPI) * radius;
//
// Move to the first point.
moveTo(xx, yy);
//
// Draw a line to each point on the arc.
for(var i=1; i<=steps; i++){
//
// Increment the angle by "angleStep".
var angle = startAngle + i * angleStep;
//
// Determine next point's coordinates using basic circle math.
xx = centerX + Math.cos(angle * twoPI) * radius;
yy = centerY + Math.sin(angle * twoPI) * radius;
//
// Draw a line to the next point.
lineTo(xx, yy);
}
}
//
// Set a line style so we can see what we are drawing.
lineStyle(0, 0xFF0000);
//
// Draw an arc with a center of (250, 250) and a radius of 200
// that starts at an angle of 45 degrees then rotates counter-
// clockwise 90 degrees. We'll span the arc with 20 evenly spaced points.
drawArc(250, 250, 200, 45/360, -90/360, 20);
//
The above code produces the following SWF file:
That may or may not be what you were expecting to see. The thing to note about the above SWF is that the point with no angle of rotation (0 degrees) is at the 3 o'clock position. Moving the the angle to better suit your needs is a very simple matter. If you want the point with no rotation to be at 12 o'clock you subtract .25 (a quarter of a turn) from your start angle like so:
function drawArc(centerX, centerY, radius, startAngle, arcAngle, steps){
//
// Rotate the point of 0 rotation 1/4 turn counter-clockwise.
startAngle -= .25;
//
var twoPI = 2 * Math.PI;
var angleStep = arcAngle/steps;
var xx = centerX + Math.cos(startAngle * twoPI) * radius;
var yy = centerY + Math.sin(startAngle * twoPI) * radius;
moveTo(xx, yy);
for(var i=1; i<=steps; i++){
var angle = startAngle + i * angleStep;
xx = centerX + Math.cos(angle * twoPI) * radius;
yy = centerY + Math.sin(angle * twoPI) * radius;
lineTo(xx, yy);
}
}
lineStyle(0, 0xFF0000);
drawArc(250, 250, 200, 45/360, -90/360, 20);
//
The above code produces the following SWF:
So there you have it. All the code needed to draw an arc or plot the points along a segment of a circle's circumference. If you're looking for an easy challenge, try modifying the code so it draws a wedge (like a slice of pie) rather than an arc.
Update: The next tutorial in this series is How to Swing a Pendulum Arc.
What if you want to draw the arc approximated as bezier curves, rather than a lot of little lines?