Beautifl - Flash Gallery

Preview

葉序開度 - Divergence of Phyllotaxy -
Aquioux 2010年2月20日 MIT License
?
葉序開度 - Divergence of Phyllotaxy -  
----------  
参考:「黄金比」 創元社(アルケミスト双書) スコット・オルセン著・藤田優里子訳 P12 「葉序のパターン」  
    http://www.amazon.co.jp/gp/product/4422214756?ie=UTF8&tag=laxcomplex-22&linkCode=as2&camp=247&creative=1211&creativeASIN=4422214756  
参考:「フィボナッチ数列と葉序」 http://www.dainippon-tosho.co.jp/mathlab/flash/no_002/math2.html  
参考:「フィボナッチ数と植物」 http://mshi.no.coocan.jp/pukiwiki/?%B8%A6%B5%E6%BC%BC%2F%A5%D5%A5%A3%A5%DC%A5%CA%A5%C3%A5%C1%BF%F4%A4%C8%BF%A2%CA%AA  
----------  
解説:http://aquioux.blog48.fc2.com/blog-entry-692.html  
----------  
@author Aquioux(Yoshida, Akio)
      package {
    import com.bit101.components.HSlider;
    import com.bit101.components.RadioButton;
    import com.bit101.components.Label;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.events.TimerEvent;
    import flash.utils.Timer;
    import frocessing.color.ColorHSV;
    [SWF(width = "465", height = "465", frameGOLDEN_RATIO = "30", backgroundColor = "#000000")]
    
    /**
     * 葉序開度 - Divergence of Phyllotaxy -
     * ----------
     * 参考:「黄金比」 創元社(アルケミスト双書) スコット・オルセン著・藤田優里子訳 P12 「葉序のパターン」
     *     http://www.amazon.co.jp/gp/product/4422214756?ie=UTF8&tag=laxcomplex-22&linkCode=as2&camp=247&creative=1211&creativeASIN=4422214756
     * 参考:「フィボナッチ数列と葉序」 http://www.dainippon-tosho.co.jp/mathlab/flash/no_002/math2.html
     * 参考:「フィボナッチ数と植物」 http://mshi.no.coocan.jp/pukiwiki/?%B8%A6%B5%E6%BC%BC%2F%A5%D5%A5%A3%A5%DC%A5%CA%A5%C3%A5%C1%BF%F4%A4%C8%BF%A2%CA%AA
     * ----------
     * 解説:http://aquioux.blog48.fc2.com/blog-entry-692.html
     * ----------
     * @author Aquioux(Yoshida, Akio)
     */
    public class Main extends Sprite {
        
        private const GOLDEN_RATIO:Number = (Math.sqrt(5) - 1) / 2;    // 黄金比(内率)
        private const NUM_OF_DOT:uint = 360;                // 生成する Dot の数
        private const RADIAN90:Number = Math.PI / 2;        // 90度のときのラジアン値
        private const CX:Number = stage.stageWidth / 2;
        private const CY:Number = stage.stageHeight / 2;

        private var dots:Array = [];    // Dot 格納配列
        
        private var label:Label;
        private var slider:HSlider;
        private var selectedRadioButton:RadioButton;
        
        private var isAuto:Boolean = false;
        private var autoValue:Number;
        private var timer:Timer;
        
        public function Main():void {
            // Dot の生成
            var hsv:ColorHSV = new ColorHSV();
            var dist:Number = 0.0;
            var n:uint = NUM_OF_DOT;
            var cx:Number = CX;
            var cy:Number = CY;
            var goldenRatio:Number = GOLDEN_RATIO;
            for (var i:int = 0; i < n; i++) {
                hsv.h = i;
                var dot:Dot = new Dot(Math.sqrt(dist) * goldenRatio, hsv.toRGB().value);
                dot.x = cx;
                dot.y = cy;
                addChild(dot);
                dots.push(dot);
                dist += goldenRatio;
            }
            
            // スライダー
            slider = new HSlider(this, 0, 0, sliderHandler);
            slider.width = stage.stageWidth;
            var max:Number = 360.0;
            var min:Number = 0.0;
            slider.setSliderParams(min, max, min);
            // ラベル
            label = new Label(this, 5, slider.height + 5);
            // ラジオボタン
            var labels:Array = [    // ラジオボタンラベル
                "degree : 180 (1/2 Phyllotaxis)",
                "degree : 120 (1/3 = 2/3 Phyllotaxis)",
                "degree : 144 (2/5 = 3/5 Phyllotaxis)",
                "degree : 135 (3/8 = 5/8 Phyllotaxis)",
                "degree : 138.5 (5/13 = 8/13 Phyllotaxis)",
                "degree : 137.3 (Fibonacci - 0.2)",
                "degree : 137.5 (Fibonacci)",
                "degree : 137.6 (Fibonacci + 0.1)",
                "degree : 222.5 (360 - Fibonacci)",
                "degree : 85 (360 - Fibonacci * 2)",
                "degree : 99.5 (Lucas)",
                "degree : 260.5 (360 - Lucas)",
                "degree : 161 (360 - Lucas * 2)",
                "degree : 61.5 (360 - Lucas * 3)",
                "degree : 237 (Fibonacci + Lucas)",
                "degree : 38 (Fibonacci - Lucas)",
                "autoStart(++0.1)"
            ];
            n = labels.length;
            var handler:Function = radioHandler;
            for (i = 0; i < n; i++) {
                if (i == n - 1) handler = autoHandler;
                var radio:RadioButton = new RadioButton(this, 8, label.y + label.height + 5 + 17 * i, labels[i], false, handler);
            }
            
            // 初期配置
            dotPlace(min);
        }
        
        // ラジオボタンハンドラ
        private function radioHandler(e:MouseEvent):void {
            // 選ばれたラジオボタンの保持
            selectedRadioButton = e.currentTarget as RadioButton;
            // オートモードだったら停止
            if (isAuto) autoStop();
            // ラジオボタンで設定した角度の取得
            var str:String = selectedRadioButton.label;
            var degree:Number = Number(str.split(" ")[2]);
            // スライダーの設定
            slider.value = degree;
            // 配置実行
            dotPlace(degree);
        }
        
        // ラジオボタンハンドラ(自動)
        private function autoHandler(e:MouseEvent):void {
            // timer が未生成ならば生成する
            if (!timer) {
                timer = new Timer(50);
                timer.addEventListener(TimerEvent.TIMER, autoStart);
            }
            // 選ばれたラジオボタンの保持
            selectedRadioButton = e.currentTarget as RadioButton;
            // オートモードフラグ
            isAuto = true;
            // 角度の取得
            autoValue = slider.value;
            // オート開始
            autoStart(null);
            timer.start();
        }
        // オート開始
        private function autoStart(e:TimerEvent):void {
            // 角度更新
            autoValue += 0.1;
            autoValue %= 360;
            // スライダーの設定
            slider.value = autoValue;
            // 配置実行
            dotPlace(autoValue);
        }
        // オート停止
        private function autoStop():void {
            isAuto = false;
            timer.stop();
            timer.reset();
        }
        
        // スライダーハンドラ
        private function sliderHandler(e:Event):void {
            // ラジオボタンのリセット
            if (selectedRadioButton) selectedRadioButton.selected = false;
            // オートモードだったら停止
            if (isAuto) autoStop();
            // 配置実行
            dotPlace(e.target.value);
        }
        
        // Dot の配置
        private function dotPlace(degree:Number):void {
            // ラベルテキストの設定
            label.text = "degree : " + String(degree);

            // 配置の設定
            var radian:Number = degree * Math.PI / 180;
            var dist:Number = 0.0;
            var n:uint = NUM_OF_DOT;
            var cx:Number = CX;
            var cy:Number = CY;
            var radian90:Number = RADIAN90;
            var goldenRatio:Number = GOLDEN_RATIO;
            for (var i:int = 0; i < n; i++) {
                var dot:Dot = dots[i];
                var angle:Number = radian * i - radian90;
                dot.x = Math.cos(angle) * dist + cx;
                dot.y = Math.sin(angle) * dist + cy;
                dist += goldenRatio;
            }
        }
    }
}


    // Dot Class
    import flash.display.Graphics;
    import flash.display.Shape;
    class Dot extends Shape {
        public function Dot(radius:Number = 5, color:uint = 0x000000) {
            var g:Graphics = graphics;
            g.beginFill(color);
            g.drawCircle(0, 0, radius);
            g.endFill();
        }
    }