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 syake 02 Jan 2012
    Embed
/**
 * Copyright syake ( http://wonderfl.net/user/syake )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/hmEJ
 */

package {
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.DisplayObject;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.geom.Point;
    import flash.text.TextField;
    import flash.text.TextFormat;
    
    /**
     * 正規分布テスト
     * @version Flash Player 9.0.124
     * @ActionScriptversion ActionScript 3.0
     * @author Hiroaki Komatsu
     */
    public class NormalDistributionTest extends Sprite {
        
        // --- property
        private var clearBitmap:BitmapData;
        private var point:Point;
        private var bitmap1:BitmapData;
        private var bitmap2:BitmapData;
        
        /**
         * constructor
         */
        public function NormalDistributionTest() {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
        
        public function init(e:Event = null):void {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            
            var w:uint = stage.stageWidth;
            var h:uint = Math.floor(stage.stageHeight / 2) - 1;
            
            // 初期設定
            clearBitmap = new BitmapData(w, h, true, 0x0);
            point = new Point(0, 0);
            this.graphics.beginFill(0x0);
            this.graphics.drawRect(0, h, w, 1);
            this.graphics.endFill();
            
            // 通常乱数
            bitmap1 = clearBitmap.clone();
            var child1:Sprite = new Sprite();
            child1.addChild(new Bitmap(bitmap1));
            addChild(child1);
            
            var txt1:TextField = new TextField();
            txt1.defaultTextFormat = new TextFormat("_等幅", 12, 0x0);
            txt1.height = 20;
            txt1.selectable = false;
            txt1.autoSize = "left";
            txt1.text = "通常乱数 ※ステージをクリックしてください";
            txt1.setTextFormat(new TextFormat("_等幅", 10, 0x666666), 5, txt1.length);
            txt1.x = 10;
            txt1.y = 10;
            addChild(txt1);
            
            // 正規分布
            bitmap2 = clearBitmap.clone();
            var child2:Sprite = new Sprite();
            child2.y = h + 1;
            child2.addChild(new Bitmap(bitmap2));
            addChild(child2);
            
            var txt2:TextField = new TextField();
            txt2.defaultTextFormat = new TextFormat("_等幅", 12, 0x0);
            txt2.height = 20;
            txt2.selectable = false;
            txt2.autoSize = "left";
            txt2.text = "正規分布 ※ステージをクリックしてください";
            txt2.setTextFormat(new TextFormat("_等幅", 10, 0x666666), 5, txt2.length);
            txt2.x = 10;
            txt2.y = h + 11;
            addChild(txt2);
            
            // イベントリスナー登録
            child1.addEventListener(MouseEvent.MOUSE_DOWN, touch1);
            child2.addEventListener(MouseEvent.MOUSE_DOWN, touch2);
        }
        
        /**
         * 通常乱数
         * @param    event
         */
        private function touch1(event:MouseEvent):void {
            // クリア
            bitmap1.copyPixels(clearBitmap, clearBitmap.rect, point);
            
            // 描画
            var x:uint, y:uint;
            for (var i:uint = 0; i < 100; i++) {
                x = Math.floor(Math.random() * bitmap1.width)
                y = Math.floor(Math.random() * bitmap1.height);
                draw(bitmap1, x, y, 0xFF0000FF);
            }
        }
        
        /**
         * 正規分布
         * @param    event
         */
        private function touch2(event:MouseEvent):void {
            // クリア
            bitmap2.copyPixels(clearBitmap, clearBitmap.rect, point);
            
            var target:DisplayObject = event.target as DisplayObject;
            var xf:Number = target.mouseX / bitmap2.width;
            var yf:Number = target.mouseY / bitmap2.height;
            
            // 描画
            var x:uint, y:uint;
            for (var i:uint = 0; i < 100; i++) {
                x = Math.floor(normalDistribution(xf, 0.2) * bitmap2.width);
                y = Math.floor(normalDistribution(yf, 0.2) * bitmap2.height);
                draw(bitmap2, x, y, 0xFFFF0000);
            }
        }
        
        /**
         * 描画
         */
        private function draw(bitmap:BitmapData, x:uint, y:uint, color:uint):void {
            bitmap.setPixel32(x-2, y  , color);
            bitmap.setPixel32(x-1, y  , color);
            bitmap.setPixel32(x  , y-2, color);
            bitmap.setPixel32(x  , y-1, color);
            bitmap.setPixel32(x  , y  , color);
            bitmap.setPixel32(x  , y+1, color);
            bitmap.setPixel32(x  , y+2, color);
            bitmap.setPixel32(x+1, y  , color);
            bitmap.setPixel32(x+2, y  , color);
        }
        
        /**
         * 正規分布の乱数を発生させる
         * @param    average        平均
         * @param    sd            標準偏差
         */
        private function normalDistribution(average:Number, sd:Number):Number {
            var t:Number = Math.sqrt(-2.0 * Math.log(1 - Math.random()));
            var u:Number = 2 * Math.PI * Math.random();
            if (Math.random() > 0.5) {
                return sd * t * Math.cos(u) + average;
            } else {
                return sd * t * Math.sin(u) + average;
            }
        }
        
    }
}