Comparing Graphics.drawPath() method with traditional Graphics API

by Fumio
Comparing Graphics.drawPath() method with traditional Graphics API, Graphics.moveTo() and Graphics.lineTo() methods.  Graphics.drawPath() method does not seem to be very fast.  But it is convenient to draw the same graphics to multiple instances.
"Comparing Graphics.drawPath() method with traditional Graphics API"
http://blog.jactionscripters.com/2011/09/13/comparing-graphics-drawpath-method-with-traditional-graphics-api/
「描画では、drawPath()を使用する方が、一連の個別のlineTo()メソッド(...[中略]...)を使用するよりもレンダリングが高速」だとされる。しかし、頂点100個の星形を1000個のShapeに描いたかぎりでは、明らかな違いはないように見える。500個にすると、少し差が出た。同じ形状を複数のインスタンスに描く場合に用いるのがよさそう。
「Graphics.drawPath()メソッドでパスの多いかたちを描く」
http://www.fumiononaka.com/TechNotes/Flash/FN1109001.html
♥1 | Line 149 | Modified 2011-09-16 09:06:01 | MIT License
play

ActionScript3 source code

/**
 * Copyright Fumio ( http://wonderfl.net/user/Fumio )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/6yyr
 */

package {
    import flash.display.Sprite;
    import flash.display.Shape;
    import flash.display.Graphics;
    import flash.display.GraphicsPathCommand;
    import flash.utils.getTimer;
    import flash.text.TextField;
    import flash.text.TextFieldAutoSize;
    import flash.text.TextFormat;
    import flash.text.TextFormatAlign;
    [SWF(width = "240",height = "180")]
    public class Testing_drawPath extends Sprite {
        private const AMOUNT:uint = 500;
        private var numVertex:uint = 100;
        private var longRadius:Number = 10;
        private var shortRadius:Number = 4;
        private var commands:Vector.<int> = new Vector.<int>();
        private var coordinates:Vector.<Number> = new Vector.<Number>();
        private var nWidth:int = stage.stageWidth;
        private var nHeight:int = stage.stageHeight;
        private var mySprite:Sprite;
        private var instances:Vector.<Shape> = new Vector.<Shape>(AMOUNT);
        private var positions:Vector.<Number> = new Vector.<Number>();
        private var colors:Vector.<uint> = new Vector.<uint>(AMOUNT);
        private var my_txt:TextField = new TextField();
        private var label_txt:TextField = new TextField();
        private var my_fmt:TextFormat = new TextFormat();
        public function Testing_drawPath() {
            createTextField();
            initialize();
            createInstances();
            test_drawPath();
            createInstances();
            test_drawPath2();
            createInstances();
            test_API();
        }
        function initialize():void {
            for (var n:uint = 0; n < AMOUNT; n++) {
                positions.push(int(Math.random() * nWidth), int(Math.random() * nHeight));
                colors[n] = int(Math.random() * 0xFFFFFF);
            }
        }
        private function createInstances():void {
            if (mySprite) {
                removeChild(mySprite);
            }
            mySprite = new Sprite();
            addChildAt(mySprite, 0);
            for (var n:uint = 0; n < AMOUNT; n++) {
                var myShape:Shape = new Shape();
                instances[n] = myShape;
                mySprite.addChild(myShape);
            }
        }
        private function test_API():void {
            var started:int = getTimer();
            for (var i:uint = 0; i < AMOUNT; i++) {
                var myShape:Shape = instances[i];
                var myGraphics:Graphics = myShape.graphics;
                myGraphics.beginFill(colors[i]);
                drawStar_w_API(numVertex, longRadius, shortRadius, myGraphics);
                myGraphics.endFill();
                myShape.x = positions[uint(i * 2)];
                myShape.y = positions[uint(i * 2 + 1)];
            }
            xTrace("Graphics API", getTimer() - started);
        }
        private function test_drawPath():void {
            var started:int = getTimer();
            for (var i:uint = 0; i < AMOUNT; i++) {
                var myShape:Shape = instances[i];
                var myGraphics:Graphics = myShape.graphics;
                myGraphics.beginFill(colors[i]);
                commands.length = 0;
                coordinates.length = 0;
                drawStar_w_drawPath(numVertex, longRadius, shortRadius, commands, coordinates);
                myGraphics.drawPath(commands, coordinates);
                myGraphics.endFill();
                myShape.x = positions[uint(i * 2)];
                myShape.y = positions[uint(i * 2 + 1)];
            }
            xTrace("Graphics.drawPath()", getTimer() - started);
        }
        private function test_drawPath2():void {
            var started:int = getTimer();
            commands.length = 0;
            coordinates.length = 0;
            drawStar_w_drawPath(numVertex, longRadius, shortRadius, commands, coordinates);
            for (var i:uint = 0; i < AMOUNT; i++) {
                var myShape:Shape = instances[i];
                var myGraphics:Graphics = myShape.graphics;
                myGraphics.beginFill(colors[i]);
                myGraphics.drawPath(commands, coordinates);
                myGraphics.endFill();
                myShape.x = positions[uint(i * 2)];
                myShape.y = positions[uint(i * 2 + 1)];
            }
            xTrace("Graphics.drawPath() 2", getTimer() - started);
        }
        private function drawStar_w_API(numVertex:uint, longRadius:Number, shortRadius:Number, myGraphics:Graphics):void {
            var nStart:Number = Math.PI;
            var nTheta:Number = nStart / numVertex;
            var nRadians:Number = 0;
            numVertex *= 2
            nStart /= 2;
            myGraphics.moveTo(0, -longRadius);
            for (var i:uint = 1; i < numVertex; i++) {
                nRadians = i * nTheta - nStart;
                myGraphics.lineTo(shortRadius * Math.cos(nRadians), shortRadius * Math.sin(nRadians));
                nRadians = (++i) * nTheta - nStart;
                myGraphics.lineTo(longRadius * Math.cos(nRadians), longRadius * Math.sin(nRadians));
            }
        }
        private function drawStar_w_drawPath(numVertex:uint,longRadius:Number,shortRadius:Number,commands:Vector.<int>, coordinates:Vector.<Number>):void {
            var nStart:Number = Math.PI;
            var nTheta:Number = nStart / numVertex;
            var nRadians:Number = 0;
            numVertex *=  2;
            nStart /=  2;
            commands.push(GraphicsPathCommand.MOVE_TO);
            coordinates.push(0, -longRadius);
            for (var i:uint = 1; i < numVertex; i++) {
                commands.push(GraphicsPathCommand.LINE_TO, GraphicsPathCommand.LINE_TO);
                nRadians = i * nTheta - nStart;
                coordinates.push(shortRadius * Math.cos(nRadians), shortRadius * Math.sin(nRadians));
                nRadians = ++i * nTheta - nStart;
                coordinates.push(longRadius * Math.cos(nRadians), longRadius * Math.sin(nRadians));
            }
        }
        private function createTextField():void {
            addChild(my_txt);
            addChild(label_txt);
            my_fmt.align = TextFormatAlign.RIGHT;
            my_txt.x +=  50;
            my_txt.defaultTextFormat = my_fmt;
            my_txt.autoSize = TextFieldAutoSize.RIGHT;
            my_txt.background = true;
            my_txt.backgroundColor = 0xFFFFFF;
            label_txt.autoSize = TextFieldAutoSize.LEFT;
            label_txt.background = true;
            label_txt.backgroundColor = 0xFFFFFF;
        }
        private function xTrace(_str:String,n:int):void {
            my_txt.appendText(String(n) + "\n");
            label_txt.appendText(_str + ":" + "\n");
        }
    }

}