
I recently had a project in which I needed to draw a sort of graph in which there is a center circle, and wedge shaped pieces that surround that circle. Turns out drawing even drawing an arc is difficult in flash (much less a wedge, much less a wedge that has an inner radius). I went about this all the wrong ways until I found a package by Lee Brimelow that allows you to draw a wedge - albeit without any center radius. This was close (a pie, not a donut), and seemed to be the most streamlined code I’d found so far. But how to get that inner radius (the donut hole)? Turns out when drawing in Flash, if you cover a previous shape with a new shape, it cuts out any overlap (sort of like the add and subtract pathfinder tools in Illustrator). So, all I had to do was start my fill, draw the original wedge, then draw a new arc whose radius was equal to the desired inner radius of the first wedge in order to subtract out that center piece. Here’s the code:
function drawArc(arcRef:Sprite, sx:int, sy:int, radius:int, arc:int, startAngle:int=0){
var segAngle:Number;
var angle:Number;
var angleMid:Number;
var numOfSegs:Number;
var ax:Number;
var ay:Number;
var bx:Number;
var by:Number;
var cx:Number;
var cy:Number;
// Move the pen
arcRef.graphics.moveTo(sx, sy);
// No need to draw more than 360
if (Math.abs(arc) > 360)
{
arc = 360;
}
numOfSegs = Math.ceil(Math.abs(arc) / 45);
segAngle = arc / numOfSegs;
segAngle = (segAngle / 180) * Math.PI;
angle = (startAngle / 180) * Math.PI;
// Calculate the start point
ax = sx + Math.cos(angle) * radius;
ay = sy + Math.sin(angle) * radius;
// Draw the first line
arcRef.graphics.lineTo(ax, ay);
// Draw the arc
for (var i:int=0; i<numOfSegs; i++)
{
angle += segAngle;
angleMid = angle - (segAngle / 2);
bx = sx + Math.cos(angle) * radius;
by = sy + Math.sin(angle) * radius;
cx = sx + Math.cos(angleMid) * (radius / Math.cos(segAngle / 2));
cy = sy + Math.sin(angleMid) * (radius / Math.cos(segAngle / 2));
arcRef.graphics.curveTo(cx, cy, bx, by);
}
// Close the wedge
arcRef.graphics.lineTo(sx, sy);
}
var myArc:Sprite = new Sprite();
myArc.graphics.beginFill(0xcccccc, 1);
drawArc(myArc, 275, 200, 150, 35,-90); //spriteName, startX, startY, radius, arcAngle, startAngle
drawArc(myArc, 275, 200, 60, 35,-90); //subtract out the middle by drawing a new circle over the top of it
myArc.graphics.endFill();
this.addChild(myArc);