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

ロジスティック写像の分岐図

Get Adobe Flash player
by Aquioux 10 Jan 2014
/**
 * Copyright Aquioux ( http://wonderfl.net/user/Aquioux )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/w6mF
 */

package {
    //import aquioux.display.colorUtil.RGBWheel;
    import com.bit101.components.HUISlider;
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Graphics;
    import flash.display.Shape;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    [SWF(width = "465", height = "465", frameRate = "60", backgroundColor = "#ffffff")]
    /**
     * ロジスティック写像の分岐図
     * x -> a * x * (1 - x)  漸化式
     * 0 <= a <= 4, 0 <= x0 <= 1
     * @see http://aquioux.net/blog/?p=3848
     * @author YOSHIDA, Akio
     */
    public class Main extends Sprite {
        // 描画サイズ
        private const IMAGE_WIDTH:int  = 400;
        private const IMAGE_HEIGHT:int = 400;

        // ロジスティック写像漸化式のループ回数
        private const LOGISTIC_LOOP_LIMIT:int = 10000;

        // 描画用ループカウンター
        private var drawLoopCnt_:int;            // 最大値は IMAGE_WIDTH

        // パラメータ a
        private var a_:Number;                    // パラメータ a
        private var aShift_:Number;                // 描画開始 a 値
        private var aAdd_:Number;                // a 増分
        private const A_REPEAT_LIMIT:int = 250;    // 横軸 1 ピクセルごとの a の計算回数

        // 色用パラメータ
        private var angle_:Number;                // RGBWheel 用角度
        private var angleAdd_:Number;            // 角度増分

        // ビューア
        private var viewBmd_:BitmapData;
        static private const FILL_COLOR:uint = 0x000000;


        /**
         * コンストラクタ
         */
        public function Main():void {
            // 背景を黒にする
            var back:Shape = new Shape();
            var g:Graphics = back.graphics;
            g.beginFill(FILL_COLOR);
            g.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
            g.endFill();
            addChild(back);
            // ビューア
            viewBmd_ = new BitmapData(IMAGE_WIDTH, IMAGE_HEIGHT, false, FILL_COLOR);
            var bm:Bitmap = new Bitmap(viewBmd_);
            bm.x = (stage.stageWidth  - IMAGE_WIDTH)  / 2 >> 0;
            bm.y = (stage.stageHeight - IMAGE_HEIGHT) / 2 >> 0;
            addChild(bm);
            // スライダー
            var slider:HUISlider = new HUISlider(this, 0, bm.y + bm.height + 5, "a:start point");
            slider.width = stage.stageWidth -10;
            slider.labelPrecision = 7;
            slider.tick = Math.pow(10, -slider.labelPrecision);
            slider.setSliderParams(0, 4, 3.5699456);
            slider.addEventListener(MouseEvent.MOUSE_UP, function():void { start(slider.value) } );

            // 初回の描画
            start(slider.value);
        }

        // 描画開始
        private function start(a:Number):void {
            // イベントハンドラ削除
            removeEventListener(Event.ENTER_FRAME, update);
            // ビューア初期化
            viewBmd_.fillRect(viewBmd_.rect, FILL_COLOR);
            // a 変動用ループカウンター & 描画X軸座標
            drawLoopCnt_ = 0;
            // パラメータ a
            a_    = a;
            aAdd_ = (4 - a_) / (IMAGE_WIDTH * A_REPEAT_LIMIT);
            // 色用パラメータ
            angle_    = Math.random() * Math.PI * 2;
            angleAdd_ = (Math.random() + 1) * Math.PI / (IMAGE_WIDTH * A_REPEAT_LIMIT);

            // 描画ループ
            addEventListener(Event.ENTER_FRAME, update);
        }

        // 描画ループ
        private function update(event:Event):void {
            // 描画
            viewBmd_.lock();
            for (var j:int = 0; j < A_REPEAT_LIMIT; j++) {
                // 計算
                a_ += aAdd_;
                var currentX:Number = Math.random();
                var i:int = LOGISTIC_LOOP_LIMIT;
                while (i--) currentX = a_ * currentX * (1 - currentX);
                // 描画
                angle_ += angleAdd_;
                viewBmd_.setPixel(drawLoopCnt_, (1 - currentX) * IMAGE_HEIGHT - 1, RGBWheel.getRadianColor(angle_));
            }
            viewBmd_.unlock();
            // 次のループへ向けて
            ++drawLoopCnt_;
            // 終了判定
            if (drawLoopCnt_ > IMAGE_WIDTH) removeEventListener(Event.ENTER_FRAME, update);
        }
    }
}


//package aquioux.display.colorUtil {
    /**
     * コサインカーブで色相環的に RGB を計算
     * @author YOSHIDA, Akio
     */
    /*public*/ class RGBWheel {
        /**
         * 彩度(HSV の彩度 S と同じ扱い)
         */
        static public function get s():Number { return _s; }
        static public function set s(value:Number):void {
            if (value < 0.0) value = 0.0;
            if (value > 1.0) value = 1.0;
            _s = value;
        }
        static private var _s:Number = 1.0;
        /**
         * 明度(HSV の明度 V と同じ扱い)
         */
        static public function get v():Number { return _v; }
        static public function set v(value:Number):void {
            if (value < 0.0) value = 0.0;
            if (value > 1.0) value = 1.0;
            _v = value;
        }
        static private var _v:Number = 1.0;

        /**
         * 角度 angle に応じた RGB を得る(弧度法指定 radian)
         * @param    radian    角度(弧度法)
         * @return    色(0xRRGGBB)
         */
        static public function getRadianColor(radian:Number):uint {
            var r:uint = (Math.cos(radian)                      + 1) * 0xff >> 1;
            var g:uint = (Math.cos(radian + 2.0943951023931953) + 1) * 0xff >> 1;
            var b:uint = (Math.cos(radian - 2.0943951023931953) + 1) * 0xff >> 1;
            // 2.0943951023931953 = Math.PI * 2 / 3 radian(= 120 degree)
            if (_s != 1.0) {
                r += shiftS(r);
                g += shiftS(g);
                b += shiftS(b);
            }
            if (_v != 1.0) {
                r -= shiftV(r);
                g -= shiftV(g);
                b -= shiftV(b);
            }
            return r << 16 | g << 8 | b;
        }
        /**
         * 角度 angle に応じた RGB を得る(度数法指定 degree)
         * @param    degree    角度(度数法)
         * @return    色(0xRRGGBB)
         */
        static public function getDegreeColor(degree:Number):uint {
            return getRadianColor(degree * 0.017453292519943295);
        }


        /**
         * 彩度の反映
         * @param    gray    諧調(0~255)
         * @return    諧調のシフト値
         * @private
         */
        static private function shiftS(gray:uint):uint {
            return (0xff - gray) * (1 - _s) >> 0;
        }
        /**
         * 明度の反映
         * @param    gray    諧調(0~255)
         * @return    諧調のシフト値
         * @private
         */
        static private function shiftV(gray:uint):uint {
            return gray * (1 - _v) >> 0;
        }
    }
//}