forked from: forked from: forked from: forked from: flash on 2009-5-1
package{
import flash.display.*;
import flash.geom.Point;
import flash.events.*;
import flash.text.*;
import flash.utils.*;
[SWF(width="400", height="400", backgroundColor="#000000", frameRate="15")]
public class mandelbrot extends Sprite{
//キャンバスサイズ
private const WIDTH:int = 400;
private const HEIGHT:int = 400;
//マンデルブロ集合パラメータ
private var repMax:int = 256; //最大計算回数
private var real:Number = -1.74972763; //実数部
private var imag:Number = -3.41468548e-005; //虚数部 (-2≦ a ≦0.5 , -1.25≦ b ≦1.25 の範囲)
private var zoom:Number = 1; //拡大率
private var scale:Number; //描画範囲
private var a:Number;
private var b:Number;
private var step:Number;
//表示用
private var canvas:Sprite;
private var pt:Point;
private var bmp:BitmapData;
private var info:TextField;
private var fmt:TextFormat;
private var fstop:Boolean = false;
private var fpsInfo:TextField;
private var update_time:int = 500; // 表示が変わる時間(ミリ秒)
private var draw_count:int = 0; // 描画カウント
private var old_timer:Number = getTimer(); // 時間待避
public function mandelbrot() {
addEventListener(Event.ADDED_TO_STAGE, init);
addEventListener(Event.REMOVED_FROM_STAGE, onRemoveFromStage);
}
private function init(e:Event):void {
stage.scaleMode = "noScale";
canvas = new Sprite();
pt = new Point();
bmp = new BitmapData(WIDTH, HEIGHT, false, 0xefefef);
info = new TextField();
fmt = new TextFormat("Arial",12,0xffffff,true);
fmt.align = TextFormatAlign.RIGHT;
info.autoSize = TextFieldAutoSize.RIGHT;
info.x = 390;
info.y = 360;
info.defaultTextFormat = fmt;
fpsInfo = new TextField();
fpsInfo.autoSize = TextFieldAutoSize.LEFT;
fpsInfo.x = 10;
fpsInfo.y = 360;
fpsInfo.defaultTextFormat = fmt;
this.addChild(canvas);
canvas.addChild(new Bitmap(bmp));
canvas.addChild(info);
canvas.addChild(fpsInfo);
this.addEventListener(MouseEvent.CLICK, pause);
this.addEventListener(Event.ENTER_FRAME, drawMandelbrot,false,1,true);
this.addEventListener(Event.ENTER_FRAME, fpsCount, false, 1, true);
}
private function drawMandelbrot(e:Event):void {
var old_time:int = getTimer();
zoom *= 1.08;
scale = 1.0/zoom;
a = real;
b = imag;
step = scale / WIDTH;
if (zoom > 6.0e+014) {
this.removeEventListener(Event.ENTER_FRAME, drawMandelbrot);
this.removeEventListener(MouseEvent.CLICK, pause);
}
bmp.lock();
for(var y:int = 0; y<HEIGHT; y++){
for(var x:int = 0; x<WIDTH; x++){
pt.x = x;
pt.y = y;
calcMandelbrot();
a += step;
}
a = real;
b += step;
}
bmp.unlock();
info.text = "Zoom: " + Math.floor(zoom) + "x\n";
}
//マンデルブロ集合の計算
private function calcMandelbrot():void {
var xi:Number = 0;
var yi:Number = 0;
var xip:Number = 0;
var yip:Number = 0;
var n:int = 0;
while (n < repMax) {
xip = xi*xi-yi*yi+a;
yip = 2*xi*yi+b;
xi = xip;
yi = yip;
//発散判定
if (xi*xi+yi*yi > 4) break;
n++;
}
bmp.setPixel(pt.x, pt.y, getColor(n));
}
private function getColor(n:int):uint {
var r:uint = ((n-64) & 0x2f) <<2;
var g:uint = ((n-32) & 0x1f) <<3;
var b:uint = (n & 0xf) <<4;
return r << 16 | g << 8 | b;
}
public function pause(e:Event):void {
if(!fstop){
this.removeEventListener(Event.ENTER_FRAME, drawMandelbrot);
fstop = true;
info.appendText("Pause..");
}else{
this.addEventListener(Event.ENTER_FRAME, drawMandelbrot);
fstop = false;
}
}
private function fpsCount(e:Event):void {
draw_count += 1;
if (getTimer()-old_timer >= update_time) {
var fps:Number = draw_count * 1000 / (getTimer() - old_timer);
fpsInfo.text = ""Math.floor(fps * 10) / 10;
old_timer = getTvc+imer();
draw_count = 0;
}
}
private function onRemoveFromStage(e:Event):void{
removeEventListener(Event.ENTER_FRAME, drawMandelbrot);
//trace("removed!!");
}
}
}