Fractals @ 24 FPS
http://en.wikipedia.org/wiki/Iterated_function_system
/**
* Copyright yonatan ( http://wonderfl.net/user/yonatan )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/qR3J
*/
// forked from yonatan's Tweening Sheep (realtime fractal generator)
// http://en.wikipedia.org/wiki/Iterated_function_system
package
{
import flash.display.*;
import flash.events.*;
import flash.filters.*;
import flash.geom.*;
import flash.utils.*;
import flash.text.*;
import flash.ui.Mouse;
import __AS3__.vec.Vector;
import gs.TweenMax;
import gs.easing.*;
import net.hires.debug.Stats;
[SWF(backgroundColor = "0x000000", frameRate = "24")]
public class Main extends Sprite
{
public function Main():void
{
Wonderfl.capture_delay( 30 );
init(stage.stageWidth, stage.stageHeight);
addChild(view);
addChild(new Stats());
addChild( tf = new TextField );
tf.y = 100;
tf.width = stage.stageWidth;
tf.textColor = 0xFFFFFF;
stage.quality = "low";
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
Mouse.cursor = flash.ui.MouseCursor.BUTTON;
stage.addEventListener(MouseEvent.CLICK, onClick);
addEventListener(Event.ENTER_FRAME, onEnter);
}
private function onClick(e:MouseEvent):void
{
change();
}
private var oldTime:Number = 0;
private function adjustToFrameRate():void {
const DAMP:Number = 10;
tf.text = "Iterations/Frame: " + numIterations;
// maintain a constant framerate
var newTime:Number = getTimer();
var iterPerMs:Number = numIterations / (newTime - oldTime);
oldTime = newTime;
numIterations = (numIterations * DAMP + (1000/stage.frameRate) * iterPerMs) / (DAMP+1);
}
private function onEnter(e:Event):void
{
transforms[0].rotation += 0.012;
transforms[1].rotation -= 0.003;
transforms[2].rotation += 0.005;
transforms[3].rotation -= 0.007;
draw();
adjustToFrameRate();
}
private var w: int;
private var h: int;
private var mw: int;
private var mh: int;
private const SCREEN_SCALE:Number = 150;
private var view: Bitmap;
private var bmpData: BitmapData;
private var buffer: Vector.<uint>;
private var numIterations:uint = 50000;
private static const NUM_TRANSFORMS:uint = 4;
private var transforms:Vector.<Transform>;
private var tonedown:ColorTransform;
private var filter:BlurFilter;
private var tf:TextField;
private function init(w: int, h: int):void
{
this.w = w;
mw = w >> 1;
this.h = h;
mh = h >> 1;
bmpData = new BitmapData(w, h, false, 0x00000000);
stage.fullScreenSourceRect = bmpData.rect;
view = new Bitmap(bmpData);
tonedown = new ColorTransform(
.92,.92,.92,.92,
-5,-5,-5,-5);
filter = new BlurFilter(1.5, 1.5, 1);
// init matrix and color arrays
transforms = new Vector.<Transform>;
for( var i:uint = 0; i < NUM_TRANSFORMS; i++ ) {
transforms.push( new Transform );
}
change();
}
private var curx:Number = 0;
private var cury:Number = 0;
private var color:uint = 0xFFFFFF;
private var topleft:Point = new Point(0,0);
private function draw(): void
{
var b: Vector.<uint> = buffer;
var bi: uint; // buf idx
var ti: int; // transform idx
bmpData.lock();
b = bmpData.getVector(bmpData.rect);
var screenx:int, screeny:int;
var newx:Number;
var xform:Transform;
var rnd:Number;
for( var i:uint = 0; i < numIterations; i++ ) {
xform = transforms[int(Math.random()*NUM_TRANSFORMS)];
// It's too bad that Matrix.transformPoint creates a new Point object
newx = curx * xform.a + cury * xform.b + xform.tx;
cury = curx * xform.c + cury * xform.d + xform.ty;
curx = newx;
screenx = curx * SCREEN_SCALE + mw;
screeny = cury * SCREEN_SCALE + mh;
color = ((color & 0xFEFEFE) + (xform.color & 0xFEFEFE)) >>> 1;
if( screenx >= 0 && screenx < w && screeny >= 0 && screeny < h )
{
bi = screeny * w + screenx;
b[bi] = ((color & 0xFEFEFE) + (b[bi] & 0xFEFEFE)) >>> 1;
}
}
bmpData.setVector(bmpData.rect, b);
bmpData.applyFilter(bmpData, bmpData.rect, topleft, filter);
bmpData.colorTransform(bmpData.rect, tonedown);
bmpData.unlock();
}
private function change(): void
{
for( var i:uint = 0; i < NUM_TRANSFORMS; i++ ) {
TweenMax.to( transforms[i], 3.5, {
delay: i/6,
ease: Bounce.easeOut,
tx: Math.random() * 2 - 1,
ty: Math.random() * 2 - 1,
scaleX: Math.random() * 0.5 + 0.25,
scaleY: Math.random() * 0.5 + 0.25,
rotation: transforms[i].rotation + (Math.random() - 0.5) * 2 * Math.PI,
hexColors:{color:Math.random()*0xFFFFFF | 0x202020} } );
}
}
}
}
import flash.geom.*;
// ugly tween wrapper
class Transform extends Matrix {
private var _x:Number = 0;
private var _y:Number = 0;
private var _scaleX:Number = 1;
private var _scaleY:Number = 1;
private var _rotation:Number = 0;
public var color:uint = 0xFFFFFF;
public var probability:Number;
public function set rotation( angle:Number ):void {
_rotation = angle;
update();
}
public function set scaleX( value:Number ):void {
_scaleX = value;
update();
}
public function set scaleY( value:Number ):void {
_scaleY = value;
update();
}
public function get rotation():Number {
return _rotation;
}
public function get scaleX():Number {
return _scaleX;
}
public function get scaleY():Number {
return _scaleY;
}
private function update():void {
var tmpty:Number = ty;
var tmptx:Number = tx;
identity();
scale( _scaleX, _scaleY );
rotate( _rotation );
ty = tmpty;
tx = tmptx;
}
}