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.
@Tyler, I’m not sure what you’re trying to do or how you’re trying to do it but it sounds like the simple solution is to increase the size of each arc segment to fill in the gaps.
Thank you very much for this post/tutorial!
I was curious if you may be able to assist me in a problem I am having. I’m trying to draw a series of arcs to form a circle. Essentially this is one circle made up of N interactive arcs.
I’m using your arc code as a base, however, I can’t find a way to have the arcs sit next to each other without any overlapping/gaps.
Any suggestions/thoughts?
Thanks in advance!
this is awesome, i was searching for this for a long time…
thanx again…
Thank You at first for your work , but i tried to make it with a Visual Csharp 2005 code but i couldn`t , but i`m trying to do it using a drawline command but no gain, so i would ask if you can show me the way to do that please if you know..and thankx again….
[…] Update: The next tutorial in this series is How to Draw an Arc with ActionScript. […]
[…] my previous article explaining How to Draw an Arc with ActionScript a few readers asked how to simulate the swing of a pendulum or the swaying motion of a falling […]
How to do a movement on a pendulum bob in arc motion? I cant seem to see the code in this area.
Yes those are really exciting libraries of code!
Here’s what my project looks like so far.
http://www.patrickmatte.com/stuff/sidlee/montreal2/
Patrick, thanks for the excellent resource link, it’s extremely robust. FUIcomponents are outside my current grasp, but that’s for another time.
What i want to do is to get the x,y of the points to create the curve, then create vertex3D’s in papervision with those points, render the papervision scene, then get the 2D screen x,y of the vertex’s and draw the resulting curve.
So since my curve is in a 3d space, one could move the camera real close to it and see all the little straight lines if i were to use this method. But with curveTo, the curve will stay sharp.
But i’ve found what i was looking for here:
http://www.adobe.com/devnet/flash/articles/adv_draw_methods.html
Thanks anyway!
Patrick, using curveTo isn’t much more efficient than drawing all these little lines because Flash internally converts all curves to a series of short straight lines. You can view my CurveTo Visualization article to see how it’s done.
I was looking for something that would use curveTo() instead of drawing all these little lines that create the arc. I guess it`d be more optimized to use curveTo().
@ worked:
A correction: I would reduce the radius to make the increments more convincing in the animation.
@ PiXELWiT:
Thank you for the well-explained function! It’s exactly what I hoped to find.
@ worked:
I would (and likely will) use this to animate by using the drawArc function in an onEnterFrame function. Of course I would reduce the steps to a very small number so as not to move the MC too quickly along the arc plot.
Now how would one animate an object in an arc motion? Like when a leaf falls…