正規分布テスト
平均値の付近に集積するような確率分布を扱う方法があったので試してみました。
このサンプルでは、通常の乱数と正規分布との違いを比べています。
それぞれのステージの任意の場所をクリックしてください。
正規分布のステージでは、クリックした座標の中心から乱数が集まるようになっています。
/**
* 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;
}
}
}
}