forked from: Mandelbrot
Mandelbrot
by rect (http://blog.r3c7.net/)
tesselated rendering (click to see it in action), 256x256 px, 60 iterations
/**
* Copyright yonatan ( http://wonderfl.net/user/yonatan )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/7RvW
*/
// forked from rect's Mandelbrot
//
// Mandelbrot
// by rect (http://blog.r3c7.net/)
//
// tesselated rendering (click to see it in action), 256x256 px, 60 iterations
package
{
import flash.events.*;
import flash.display.*;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.utils.getTimer;
import flash.ui.Mouse;
import frocessing.color.ColorHSV;
[SWF(backgroundColor="#000000")]
public class main extends Sprite
{
private const w:uint = 256;
private const h:uint = 256;
private var cont:Bitmap;
private var zero:Point = new Point(0,0);
private var bmd:BitmapData;
private var buffer:Vector.<uint>;
private var zoom:Number = 1;
private var mx:Number = -0.5;
private var my:Number = 0;
private var maxIteration:int = 60;
private var rot:Number = 0;
private var fill:Boolean = true;
public function main():void
{
stage.frameRate = 30;
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.quality = StageQuality.MEDIUM;
Mouse.cursor = flash.ui.MouseCursor.BUTTON;
bmd = new BitmapData(w, h, false, 0x000000);
cont = new Bitmap(bmd);
addChild(cont);
cont.width = stage.stageWidth;
cont.height = stage.stageHeight;
cont.x = (stage.stageWidth - cont.width) / 2;
cont.y = (stage.stageHeight - cont.height) / 2;
buffer = new Vector.<uint>( w*h, true );
addEventListener(Event.ENTER_FRAME, update);
stage.addEventListener(MouseEvent.CLICK, function(e:*):void{ fill = !fill });
}
private function update(e:Event):void
{
var pixels:uint = w * h;
rot += 1;
zoom = 21 + Math.sin(rot * Math.PI/180) * 20;
mx = (Math.sin(rot * Math.PI/180) * 0.5) -1.5;
my = Math.sin(rot * Math.PI/180) * 0.28;
for (var j:int = 0; j < pixels; j++) buffer[j]=0;
tesselate( 0, 0,w-1,h-1 );
bmd.setVector(bmd.rect, buffer);
}
private function tesselate( x1:uint, y1:uint, x2:uint, y2:uint ):void {
if( x2==x1 && y2==y1 ) return;
var x:uint, y:uint;
var color:uint = getAndSetPixel( x1, y1 );
var split:Boolean = false;
for( x=x1; x<=x2; x++ ) {
split = split || (color != getAndSetPixel( x, y1 ));
split = split || (color != getAndSetPixel( x, y2 ));
}
for( y=y1; y<=y2; y++ ) {
split = split || (color != getAndSetPixel( x1, y ));
split = split || (color != getAndSetPixel( x2, y ));
}
if( x2-x1 < 2 && y2-y1 < 2 ) return;
if( split ) {
if( x2-x1 > y2-y1 ) {
tesselate( x1, y1, (x1+x2)/2, y2 );
tesselate( (x1+x2)/2, y1, x2, y2 );
} else {
tesselate( x1, y1, x2, (y1+y2)/2 );
tesselate( x1, (y1+y2)/2, x2, y2 );
}
} else {
if( !fill ) color = 0xFFCC8800;
for( y = y1+1; y < y2; y++ ) {
for( x = x1+1; x < x2; x++ ) {
buffer[y*w+x] = color;
}
}
}
}
private function getAndSetPixel( x:int, y:int ):uint {
var idx:uint = y*w+x;
if( buffer[idx] == 0 ) {
var i:uint = calc( 1.5 * (x - w/2) / (zoom * w/2) + mx, (y - h/2) / (zoom * h/2) + my );
var hsv:ColorHSV = new ColorHSV((i + 192) & 255, 0.9, (240 * Number(i < maxIteration))*0.01, 1);
var rgb:uint = hsv.value;
buffer[idx] = rgb | 0xFF000000;
}
return buffer[idx];
}
private function calc( pr:Number, pi:Number ):uint {
var newRe:Number = 0;
var newIm:Number = 0;
var oldRe:Number = 0;
var oldIm:Number = 0;
var oldReSqr:Number = 0;
var oldImSqr:Number = 0;
var i:int = 0;
for(i= 0; i < maxIteration; i++)
{
oldRe = newRe;
oldIm = newIm;
oldReSqr = oldRe * oldRe;
oldImSqr = oldIm * oldIm;
newRe = oldReSqr - oldImSqr + pr;
newIm = 2 * oldRe * oldIm + pi;
if((oldReSqr + oldImSqr) > 4) break;
}
return i;
}
}
}