Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to draw a series of arc segments across line segments

I'm trying to draw a 'countdown' circle that will produce a visual clock, but don't like the resulting shape as it is not smooth. The code below draws and fills a series of triangles that approximate a circle when the variable 'numberOfSides' is sufficiently large, but this is both inefficient and produces an ugly 'circle.' What I would like to do is draw a series of arcs across the line segments but I don't know how to do it. Can anyone give me a prod in the right direction?

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" minWidth="955" minHeight="600" frameRate="100" creationComplete="init()">
<mx:Script>
    <![CDATA[
        private var numberOfSides:int = 10;
        private var angle:Number = 0;
        private var lineLength:int = 100;
        private var xStartingPos:int = 300;
        private var yStartingPos:int = 300;
        private var i:int = 90;//Start the drawing  at 0 to 360;
        private var speed:int = 100;
        private var timer:Timer  
        private function init():void{
            //uic.graphics.lineStyle(1);
            uic.graphics.moveTo(xStartingPos,yStartingPos);
            uic.graphics.beginFill(0xffff00);
            timer = new Timer(speed, numberOfSides + 1);
            timer.addEventListener(TimerEvent.TIMER,cont);
            timer.start()
        }
        private function cont(event:TimerEvent):void{
                angle = (Math.PI / numberOfSides * 2) * i;
                var xAngle:Number = Math.sin(angle);                 
                var yAngle:Number = Math.cos(angle);
                var xResult:int = xAngle * lineLength;
                var yResult:int = yAngle * lineLength;
                uic.graphics.lineTo(xStartingPos + xResult, yStartingPos + (yResult*-1));
                i++
        }
    ]]>
</mx:Script>
<mx:Canvas  id="uic"/>
</mx:Application>
like image 363
SimonRH Avatar asked Jan 29 '26 05:01

SimonRH


1 Answers

This could be accomplished by drawing wedges using nl.funkymonkey.drawing.DrawingShapes:

wedge-1 wedge-2 wedge-3 wedge-4 wedge-5

Draw Wedge function:

public static function drawWedge(target:Graphics, x:Number, y:Number, radius:Number, arc:Number, startAngle:Number=0, yRadius:Number=0):void
{
    if (yRadius == 0)
        yRadius = radius;

    target.moveTo(x, y);

    var segAngle:Number, theta:Number, angle:Number, angleMid:Number, segs:Number, ax:Number, ay:Number, bx:Number, by:Number, cx:Number, cy:Number;

    if (Math.abs(arc) > 360)
        arc = 360;

    segs = Math.ceil(Math.abs(arc) / 45);
    segAngle = arc / segs;
    theta = -(segAngle / 180) * Math.PI;
    angle = -(startAngle / 180) * Math.PI;
    if (segs > 0)
    {
        ax = x + Math.cos(startAngle / 180 * Math.PI) * radius;
        ay = y + Math.sin(-startAngle / 180 * Math.PI) * yRadius;
        target.lineTo(ax, ay);
        for (var i:int = 0; i < segs; ++i)
        {
            angle += theta;
            angleMid = angle - (theta / 2);
            bx = x + Math.cos(angle) * radius;
            by = y + Math.sin(angle) * yRadius;
            cx = x + Math.cos(angleMid) * (radius / Math.cos(theta / 2));
            cy = y + Math.sin(angleMid) * (yRadius / Math.cos(theta / 2));
            target.curveTo(cx, cy, bx, by);
        }
        target.lineTo(x, y);
    }
}

Example implementation, animating countdown timer:

var value:Number = 0;

addEventListener(Event.ENTER_FRAME, frameHandler);

function frameHandler(event:Event):void
{
    var g:Graphics = graphics;
    g.clear();

    value += 0.01;

    g.lineStyle(1, 0x0000ff, 0.25);
    g.beginFill(0x123456, 0.25);
    drawWedge(g, 100, 100, 50, (360 * value) % 360);
    g.endFill();
}

Any graphics line style or fill may be used; or, the fill could be used as a mask.

like image 68
Jason Sturges Avatar answered Feb 01 '26 01:02

Jason Sturges



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!