Buddhabrot

by naraba
Buddhabrot
終了まで一分
ref. http://en.wikipedia.org/wiki/Buddhabrot
♥2 | Line 75 | Modified 2009-11-28 15:04:46 | MIT License
play

ActionScript3 source code

/**
 * Copyright naraba ( http://wonderfl.net/user/naraba )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/n5TM
 */

// Buddhabrot
// 終了まで一分
// ref. http://en.wikipedia.org/wiki/Buddhabrot
package
{ 
	import flash.display.Bitmap;
	import flash.display.BitmapData;
    import flash.display.Sprite;
	import flash.utils.Timer;
	import flash.events.TimerEvent;
	
    [SWF(width="465", height="465")] 
	public class Buddhabrot extends Sprite
	{
		private static const SIZE:Number = 465;
		private static const POINTS:uint = 3000000;
		private static const ITERATIONS:uint = 1000;
		private static const TO_INFINITY:Number = 4;
		private var counters:Array;
		private var bitmap:Bitmap;
		private var canvas:BitmapData;
		private var timer:Timer = new Timer(200);
		
		public function Buddhabrot():void
		{
			Wonderfl.capture_delay(60);
			counters = new Array(SIZE*SIZE).map(function():* {
                return 0;
            });
			canvas = new BitmapData(SIZE, SIZE); 
            bitmap = new Bitmap(canvas); 
            addChild(bitmap); 
			timer.addEventListener(TimerEvent.TIMER, step);
			timer.start();
		}
		
		private function step(e:TimerEvent):void
		{
			if (timer.currentCount*10000 >= POINTS) {
				timer.stop();
			}
			render(10000);
		}
		
		private function render(points:uint):void
		{
			for (var i:uint = 0; i < points; i++) {
				var cx:Number = Math.random()*3-2;
				var cy:Number = Math.random()*3-1.5;
				if (iterate(cx, cy, true)) {
					iterate(cx, cy, false);
				}
			}
			for (var x:uint = 0; x < SIZE; x++) {
				for (var y:uint = 0; y < SIZE; y++) {
					var col:uint = counters[x+y*SIZE];
					canvas.setPixel(y, x, Math.min(col, 0xFF));
				}
			}
		}
		
		private function iterate(cx:Number, cy:Number, isFirst:Boolean):Boolean
		{
			var x:Number = 0;
			var y:Number = 0;
			for (var i:uint = 0; i < ITERATIONS; i++) {
				var nx:Number = x*x-y*y+cx;
				var ny:Number = 2*x*y+cy;
				var px:uint = int(SIZE*(nx+2)/3);
				var py:uint = int(SIZE*(ny+1.5)/3);
				if (!isFirst && px >= 0 && px < SIZE && py >= 0 && py < SIZE) {
					counters[px+py*SIZE] += 1;
				}
				if (nx*nx+ny*ny > TO_INFINITY) {
					return true;
				}
				x = nx;
				y = ny;
			}
			return false;
		}
	}
}