In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

3D (isometric) fractals @ 16 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/qfJG
 */

// forked from yonatan's Fractals @ 24 FPS
// 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 net.hires.debug.Stats;

    [SWF(backgroundColor = "0x000000", frameRate = "16")]
    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 {
            for each( var t:FTransform in transforms ) {
                t.matrix.appendRotation( 1, new Vector3D(0,1,0), new Vector3D(0,0,0) );
            }
            draw();
            adjustToFrameRate();
        }

        private var w: int;
        private var h: int;
        private var mw: int;
        private var mh: int;
        private const SCREEN_SCALE:Number = 100;
        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.<FTransform>;

        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, true, 0x00000000);
            stage.fullScreenSourceRect = bmpData.rect;
            view = new Bitmap(bmpData);
            tonedown = new ColorTransform(
                .92,.92,.92,0,
                -5,-5,-5,255);
            filter = new BlurFilter(2.5, 2.5, 1);

            // init matrix and color arrays
            transforms = new Vector.<FTransform>;
            var i:uint;
            for( i = 0; i < NUM_TRANSFORMS; i++ ) {
                transforms.push( new FTransform );
            }
            transforms[0].matrix.appendTranslation( 1,  1,  1);
            transforms[1].matrix.appendTranslation(-1, -1,  1);
            transforms[2].matrix.appendTranslation( 1, -1, -1);
            transforms[3].matrix.appendTranslation(-1,  1, -1);

            for( i = 0; i < NUM_TRANSFORMS; i++ ) {
                transforms[i].matrix.appendScale(.5,.5,.5);
            }

            //change();
        }
        
        private var curx:Number = 0;
        private var cury:Number = 0;
        private var curz: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();
            bmpData.fillRect( bmpData.rect, 0 );
            b = bmpData.getVector(bmpData.rect);

            var screenx:int, screeny:int;
            var newx:Number;
            var newy:Number;
            var xform:FTransform;
            var raw:Vector.<Number>;
            var rnd:Number;
            var zbyte:uint;

            for( var i:uint = 0; i < numIterations; i++ ) {
                xform = transforms[int(Math.random()*NUM_TRANSFORMS)];
                raw = xform.matrix.rawData;
                
                // math courtesy of umhr: http://wonderfl.kayac.com/code/9f8f55a85ed49edb59c1a313063e6abfaf4271e7
                newx = (raw[0]*curx + raw[4]*cury + raw[8]*curz) + raw[12];
                newy = (raw[1]*curx + raw[5]*cury + raw[9]*curz) + raw[13];
                curz = (raw[2]*curx + raw[6]*cury + raw[10]*curz) + raw[14];
                curx = newx;
                cury = newy;

                screenx = curx * SCREEN_SCALE + mw;
                screeny = cury * SCREEN_SCALE + mh;

                zbyte = curz <= -1 ? 0x80000000 : curz >= 1 ? 0xFF000000 : ((curz + 1) / 2 * 0x7f + 0x80) << 24;
                color = ((color & 0xFEFEFE) + (xform.color & 0xFEFEFE)) >>> 1;
                if( screenx >= 0 && screenx < w && screeny >= 0 && screeny < h )
                {
                    bi = screeny * w + screenx;
                    if( (b[bi] & 0xFF000000) < zbyte ) {
                        //b[bi] = (((color & 0xFEFEFE) + (b[bi] & 0xFEFEFE)) >>> 1) | zbyte;
                        b[bi] = color | zbyte;
                    }
                }
            }
            
            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++ ) {
                var m:Matrix3D = new Matrix3D;
                m.appendTranslation( Math.random()*2-1, Math.random()*2-1, Math.random()*2-1 );
                m.appendScale( Math.random()/2+0.25, Math.random()/2+0.25, Math.random()/2+0.25 );
                m.appendRotation( Math.random()*360, new Vector3D(Math.random(),Math.random(),Math.random()), new Vector3D(0,0,0) );
                transforms[i].tweenTo( m, Math.random()*0xFFFFFF | 0x202020 );
            }
        }
    }
}

import flash.geom.Matrix3D;
import gs.TweenMax;
import gs.easing.*;

// ugly tween wrapper
class FTransform{
    private var start:Matrix3D;
    private var finish:Matrix3D;
    public var matrix:Matrix3D;
    private var _t:Number;
    public var color:uint = Math.random()*0xFFFFFF | 0x202020;
    
    public function FTransform() {
        start = new Matrix3D;
        finish = new Matrix3D;
        matrix = new Matrix3D;
        _t = 0;
    }
    
    public function tweenTo( dest:Matrix3D, color:uint ):void {
        start = matrix;
        finish = dest;
        t = 0;
        TweenMax.to( this, 3, {
            ease: Sine.easeInOut,
            hexColors:{ color: color },
            t: 1
        } );
    }
    
    public function get t():Number { return _t }
    public function set t( value:Number ):void { 
        _t = value;
        matrix = Mtrx3D.myInterpolate( this.start, this.finish, _t );
    }
}

class Mtrx3D {
	import flash.geom.Matrix3D;
	import flash.geom.Vector3D;
	public static function myInterpolate(thisMat:Matrix3D,toMat:Matrix3D,percent:Number):Matrix3D{
		var v0:Vector3D = thisMat.decompose("quaternion")[1];
		var v1:Vector3D = toMat.decompose("quaternion")[1];
		var cosOmega:Number = v0.w*v1.w + v0.x*v1.x + v0.y*v1.y + v0.z*v1.z;
		if(cosOmega < 0){
			v1.x = -v1.x;
			v1.y = -v1.y;
			v1.z = -v1.z;
			v1.w = -v1.w;
			cosOmega = -cosOmega;
		}
		var k0:Number;
		var k1:Number;
		if(cosOmega > 0.9999){
			k0 = 1 - percent;
			k1 = percent;
		}else{
			var sinOmega:Number = Math.sqrt(1 - cosOmega*cosOmega);
			var omega:Number = Math.atan2(sinOmega,cosOmega);
			var oneOverSinOmega:Number = 1/sinOmega;
			k0 = Math.sin((1-percent)*omega)*oneOverSinOmega;
			k1 = Math.sin(percent*omega)*oneOverSinOmega;
		}
		var scale_x:Number = thisMat.decompose("quaternion")[2].x*(1-percent) + toMat.decompose("quaternion")[2].x*percent;
		var scale_y:Number = thisMat.decompose("quaternion")[2].y*(1-percent) + toMat.decompose("quaternion")[2].y*percent;
		var scale_z:Number = thisMat.decompose("quaternion")[2].z*(1-percent) + toMat.decompose("quaternion")[2].z*percent;
		
		var tx:Number = thisMat.decompose("quaternion")[0].x*(1-percent) + toMat.decompose("quaternion")[0].x*percent;
		var ty:Number = thisMat.decompose("quaternion")[0].y*(1-percent) + toMat.decompose("quaternion")[0].y*percent;
		var tz:Number = thisMat.decompose("quaternion")[0].z*(1-percent) + toMat.decompose("quaternion")[0].z*percent;
		
		//trace(thisMat.decompose("quaternion")[2].x,toMat.decompose("quaternion")[2].x,scale_x)
		
		var x:Number = v0.x*k0+v1.x*k1;
		var y:Number = v0.y*k0+v1.y*k1;
		var z:Number = v0.z*k0+v1.z*k1;
		var w:Number = v0.w*k0+v1.w*k1;
		var _q:Vector.<Number> = new Vector.<Number>(16,true);
		_q[0] = (1-2*y*y-2*z*z)*scale_x;
		_q[1] = (2*x*y+2*w*z)*scale_x;
		_q[2] = (2*x*z-2*w*y)*scale_x;
		_q[3] = 0;
		_q[4] = 2*x*y-2*w*z*scale_y;
		_q[5] = (1-2*x*x-2*z*z)*scale_y;
		_q[6] = 2*y*z+2*w*x*scale_y;
		_q[7] = 0;
		_q[8] = 2*x*z+2*w*y*scale_z;
		_q[9] = 2*y*z-2*w*x*scale_z;
		_q[10] = (1-2*x*x-2*y*y)*scale_z;
		_q[11] = 0;
		_q[12] = tx;
		_q[13] = ty;
		_q[14] = tz;
		_q[15] = 1;
		//trace(_q)
		
		var v:Vector3D = new Vector3D(v0.x*k0+v1.x*k1,v0.y*k0+v1.y*k1,v0.z*k0+v1.z*k1,v0.w*k0+v1.w*k1);
		
		//var txyz:Vector3D = new Vector3D(tx,ty,tz);
		//var m:Matrix3D=new Matrix3D();
		//m.recompose(Vector.<Vector3D>([txyz,v,new Vector3D(scale_x,scale_y,scale_z)]),"quaternion");
		//trace(m.rawData);
		return new Matrix3D(_q);
	}
}