Top | 戻る

扇形を描く

  ActionScript の Graphics クラスには扇形を描く API がありません。 扇形を描くには少し計算が必要です。 ここでは異なる2点の位置と接線の角度から、Graphics.curveTo に渡すコントロールポイントを計算する関数 getControlPoint を用意します。 この関数と円の接線と法線が直角となる性質を利用すると、扇形を描くことができます。
コントロールポイントの算出
GraphicsLib.as
package {

    import flash.display.Graphics;
    import flash.display.Sprite;
    import flash.geom.Point;


    public class GraphicsLib {

        private static const RIGHT_ANGLE : Number = Math.PI / 2;

        public static function drawPie(g : Graphics, x : Number, y : Number, r : Number, t1 : Number, t2 : Number, lineTo : Boolean = false) : void {

            // 曲線の分割数。多いほど近似の精度は高くなる。
            var div : int = Math.max(1, Math.floor(Math.abs(t1 - t2) / 0.4) );

            var lx : Number;
            var ly : Number;
            var lt : Number;

            for (var i : int = 0; i <= div; i++) {

                var ct : Number = t1 + (t2 - t1) * i / div;
                var cx : Number = Math.cos(ct) * r + x;    
                var cy : Number = Math.sin(ct) * r + y;    

                if (i == 0) {
                    if (lineTo) {
                        g.lineTo(cx, cy);            
                    } else {
                        g.moveTo(cx, cy);
                    }
                } else {
                    var cp : Point = getControlPoint(lx, ly, lt + RIGHT_ANGLE, cx, cy, ct + RIGHT_ANGLE); 
                    g.curveTo(cp.x, cp.y, cx, cy);            
                }

                lx = cx;
                ly = cy;
                lt = ct;
            }
        }
        
        public static function getControlPoint(
            x1 : Number, y1 : Number, t1 : Number,
            x2 : Number, y2 : Number, t2 : Number
        ) : Point {

            var x12 : Number = x2 - x1;
            var y12 : Number = y2 - y1;
            
            var l12 : Number = Math.sqrt(x12 * x12 + y12 * y12);
            var t12 : Number = Math.atan2(y12, x12);

            var l13 : Number = l12 * Math.sin(t2 - t12) / Math.sin(t2 - t1);

            var x3 : Number = x1 + l13 * Math.cos(t1);
            var y3 : Number = y1 + l13 * Math.sin(t1);

            return new Point(x3, y3);
        }         
    }
}
  単に線の扇形ではあまり面白くないので、種類の半径と 2種類の角度に囲まれた形を描いてみることにします。
Pie.as
package {

    import flash.display.Graphics;
    import flash.display.Sprite;


    public class Pie extends Sprite {

        public function Pie(r1 : Number, r2 : Number, t1 : Number, t2 : Number, color : uint = 0x000000, alpha : Number = 1.0) {
            var g : Graphics = graphics;
            g.beginFill(color, alpha);
            GraphicsLib.drawPie(g, 0, 0, r1, t1, t2, false);
            GraphicsLib.drawPie(g, 0, 0, r2, t2, t1, true);
            g.endFill();
        }
    }
}
PieDemo.as
package {

    import flash.display.Sprite;
    import flash.events.Event;


    public class PieDemo extends Sprite {

        public function PieDemo() {
            addPie(25, 35, 1, 0.7);
            addPie(30, 60, 2, -1.3);
            addPie(40, 65, 2, 1.3);
            addPie(50, 85, 3, -2.3);
            addPie(65, 70, 3, 2.3);
            addPie(75, 90, 4, -3.3);
            addPie(80, 95, 4, 3.3);
        }
        
        private function addPie(r1 : Number, r2 : Number, t : Number, speed : Number) : void {
            var pie : Pie = new Pie(r1, r2, 0, t, 0x6666cc, 0.5);
            pie.x = 100;
            pie.y = 100;
            pie.addEventListener(Event.ENTER_FRAME, function(e : Event) : void {
                pie.rotation += speed;
            });
            addChild(pie);
        }
    }

}
実行結果

Contents Copyright © Kazuhiko Arase