In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

ペジェ曲線 for flash10

3次までのペジェ曲線を描くサンプル 
クリックした場所を制御点に加えていきます。
/**
 * Copyright Horiuchi_H ( http://wonderfl.net/user/Horiuchi_H )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/emFj
 */

package 
{
    import flash.display.Graphics;
    import flash.display.Sprite;
    import flash.display.Stage;
    import flash.events.Event;
    import flash.events.MouseEvent;
	import flash.geom.Point;
    
    [SWF(width = 465, height = 465, frameRate = 120, backgroundColor = "#000000")]
    
    /**
     * 3次までのペジェ曲線を描くサンプル 
     * クリックした場所を制御点に加えていきます。 
     */
    public class BezierCurve extends Sprite
    {
        private static const CURVE_POINT:int = 4;
        private static const DRAW_COUNT:Number = 100;
        
        private var clickPoints:Vector.<Point> = new Vector.<Point>();
        private var frame:Number = -1;
        
        private var g:Graphics;
        
        public function BezierCurve() {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
        
        private function init(e:Event = null):void {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            // entry point
            g = this.graphics;
            
            this.stage.addEventListener(MouseEvent.CLICK, stageClickEventHandler);
            this.stage.addEventListener(Event.ENTER_FRAME, drawCurve);
        }
        
        
        private function stageClickEventHandler(event:MouseEvent):void {
            var point:Point = new Point(event.stageX, event.stageY);
            frame = 0;
            
            if (clickPoints.length >= CURVE_POINT) {
                clearStage();
                clickPoints.splice(0, clickPoints.length);
                frame = -1;
            }
            
            clickPoints.push(point);
            g.lineStyle(1, 0xffffff);
            g.drawCircle(point.x, point.y, 5.0);
            
            if (true) {
                // for debug
                g.lineStyle(1, 0x66666666);
                g.moveTo(clickPoints[0].x, clickPoints[0].y);
                for (var i:int = 1; i < clickPoints.length; i++) {
                    g.lineTo(clickPoints[i].x, clickPoints[i].y);
                }
            }
            
            if (clickPoints.length > 1) {
                var from:Point = calcBezierCurvePoint(clickPoints, 0);
                g.lineStyle(2, 0x33cc66);
                g.moveTo(from.x, from.y);
                for (var index:int = 1; index <= DRAW_COUNT; index++) {
                    var to:Point = calcBezierCurvePoint(clickPoints, index / DRAW_COUNT);
                    g.lineTo(to.x, to.y);
                    //trace(to.x + "," + to.y);
                }
            }
        }
        
        private function clearStage():void {
            g.clear();
        }
        
        private function drawCurve(event:Event = null):void {
            if (frame < 0) return;
            if (frame >= DRAW_COUNT) return;
            
            var start:Point = calcBezierCurvePoint(clickPoints, frame / DRAW_COUNT);
            var end:Point = calcBezierCurvePoint(clickPoints, (frame + 1)/ DRAW_COUNT);
            g.lineStyle(1, 0xffffff);
            g.moveTo(start.x, start.y);
            g.lineTo(end.x, end.y);
            frame++;
        }
        
        private function calcBezierCurvePoint(points:Vector.<Point>, t:Number):Point {
			if (points.length == 0)
				return new Point();
            var ps:Vector.<Point> = points;
            while (ps.length > 1) {
                var next:Vector.<Point> = new Vector.<Point>();
                for (var index:int = 0; index < ps.length - 1; index++) {
                    next.push(calcCutoffPoint(ps[index], ps[index + 1], t));
                }
                ps = next;
            }
            return ps[0];
        }
        
        private function calcCutoffPoint(startPoint:Point, endPoint:Point, t:Number):Point {
            return Point.interpolate(endPoint, startPoint, t);
        }
    }
}