Mandelbrot fractal
This is the result of me playing around with complex numbers and the Mandelbrot fractal.
Arrows or mouse: move around
Sliders to change:
zoom (scale)
iterations (n)
cut off limit (r)
[I have now removed my complex number class]
[I still have the code on my computer.]
[So if you're interested in it, send me a message!]
My class for complex numbers can do:
The basic operations:
addition
subtraction
multiplication & vector scaling
division
exponentiation (through polar form and de Moivre's formula)
Special operations:
argument
absolute value
conjugate
conjugate multiplication
(I haven't implemented complex numbers in polar form yet, and I doubt it will happen at all. It's just me playing around, after all!)
♥0 |
Line 143 |
Modified 2011-11-25 07:34:00 |
MIT License
archived:2017-03-20 09:58:37
ActionScript3 source code
/**
* Copyright antalg ( http://wonderfl.net/user/antalg )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/oLjH
*/
package {
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.text.TextField;
import flash.display.Sprite;
import com.bit101.components.HUISlider;
public class Mandelbrot extends Sprite {
public function Mandelbrot() {
_data = new BitmapData(WIDTH, HEIGHT);
addChild(new Bitmap(_data));
render();
var vals:Array = [_scale, _n , _r];
var maxes:Array = [40, 150, 100];
_sliders.push(new HUISlider (null, 0, 0, "Scale", updSliders));
_sliders.push(new HUISlider (null, 0, 0, "N (iterations)", updSliders));
_sliders.push(new HUISlider (null, 0, 0, "R (limit)", updSliders));
for(var i:int = 0; i<3; i++) {
_sliders[i].setSliderParams(0.1, maxes[i], vals[i]);
_sliders[i].y = i*20;
_sliders[i].width = 465;
addChild(_sliders[i]);
}
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyD);
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseD);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseU);
}
private var _sliders:Array = new Array();
private var _dx:Number = 0;
private var _dy:Number = 0;
private var _scale:Number = 0.8;
private var _r:Number = 20;
private var _n:Number = 35;
private var _data:BitmapData;
private const WIDTH:int = 465;
private const HEIGHT:int = 465;
private var _startPos:Point;
private var _startD:Point;
private function mouseD(e:MouseEvent):void {
if(stage.mouseY > 60) {
_startPos = new Point(stage.mouseX, stage.mouseY);
_startD = new Point(_dx, _dy);
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseM);
}
}
private function mouseU(e:MouseEvent):void {
stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseM);
}
private function mouseM(e:MouseEvent):void {
var dx:Number = 2.3/_scale/WIDTH;
var dy:Number = 2.4/_scale/HEIGHT;
_dx = _startD.x + (_startPos.x - stage.mouseX)*dx;
_dy = _startD.y + (_startPos.y - stage.mouseY)*dy;
render();
}
private function keyD(e:KeyboardEvent):void {
switch(e.keyCode) {
case 37: // Left
_dx-=0.1/_scale;
break;
case 38: // Up
_dy-=0.1/_scale;
break;
case 39: // Right
_dx+=0.1/_scale;
break;
case 40: // Down
_dy+=0.1/_scale;
break;
}
render();
}
private function updSliders(e:*):void {
_scale = _sliders[0].value;
_n = _sliders[1].value;
_r = _sliders[2].value;
render();
}
private function render():void {
renderFractal( -1.8/_scale + _dx, -1.2/_scale + _dy, 0.5/_scale + _dx, 1.2/_scale + _dy, _n, _r);
}
private function renderFractal(sX:Number, sY:Number, eX:Number, eY:Number, n:int, r:Number):void {
var x:int;
var y:int;
var dx:Number = (eX-sX)/WIDTH;
var dy:Number = (eY-sY)/HEIGHT;
_data.lock();
r*=r;
var vec:Vector.<uint> = new Vector.<uint>(HEIGHT*WIDTH);
for (x = 0; x<WIDTH;x++) {
for (y = 0; y<HEIGHT;y++) {
vec[x+y*WIDTH] = calcColor(sX+x*dx, sY+y*dy, n, r);
}
}
_data.setVector(new Rectangle(0, 0, WIDTH ,HEIGHT), vec);
_data.unlock();
}
private function calcColor(cR:Number, cI:Number, n:int, r:Number):uint {
var zR:Number = cR;
var zI:Number = cI;
var zR2:Number;
var zI2:Number;
var m:int = 1;
for(; m<n; m++) {
zR2 = zR*zR;
zI2 = zI*zI;
zI = 2*zR*zI + cI;
zR = zR2 - zI2 + cR;
if(zR2 + zI2 > r) {
var phi:Number = m-Math.log(Math.log(Math.sqrt(zR*zR+zI*zI))/Math.log(n))/Math.LN2;
var b:int = (phi*70)%((colMax<<1)-1);
b = b<=colMax?b:( ((colMax<<1)-1)-b );
return (255<<24)|(b<<16)|(b<<8)|(b/2);
}
}
return 0xFFFFFFFF;
}
private const colMax:int = 200;
////////////////////////////////////////////////////
private var traceTextField:TextField;
private function setupTrace(color:uint, x:int = 0, y:int = 0, width:int = 200, height:int = 400):void {
traceTextField = new TextField();
addChild(traceTextField);
traceTextField.textColor = color;
traceTextField.x = x;
traceTextField.y = y;
traceTextField.width = width;
traceTextField.height = height;
}
private function clear():void {
traceTextField.text = "";
}
private function trace(output:*):void {
traceTextField.text = output;
}
private function traceA(output:*):void {
traceTextField.appendText(output+"\n");
}
}
}