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

forkoptimized from: Lissajous Curve (EFLA + setVector + LUT)

EFLA

LISSAJOUS CURVE
@author Andrea Bovo (lespleen)

optimizations:
- setVector instead setPixel
- LUT sqrt/cos/sin
/**
 * Copyright lespleen ( http://wonderfl.net/user/lespleen )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/4KVF
 */

// forked from esimov's Lissajous Curve
/* @title LISSAJOUS CURVE
 *
 *@see http://wonderfl.net/c/7Cxn
 *@see http://jacksondunstan.com/articles/1190
 * 
 *@author spleen666@gmail.com
 * 
 * Added setVector + LUT optmizations.
 * 
 *
 */

package
{
    import flash.geom.Point;
    import flash.filters.BlurFilter;
    
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Graphics;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.geom.Rectangle;
   
    
    import net.hires.debug.Stats;
    
    [SWF (backgroundColor = 0xffffff, width = '465', height ='465')] 
    
    public class LissajousCurve extends Sprite
    {
        private const WIDTH:Number = stage.stageWidth
        private const HEIGHT:Number = stage.stageHeight;
        
        private var _dist:Number;
        private var _angleX:Number = 0;
        private var _angleY:Number = 0;
        private var _speedX:Number = Math.random() * 0.1 - 0.05;
        private var _speedY:Number = Math.random() * 0.1 - 0.05;
        private var _points:Array = [];
        
        private var _bmd:BitmapData;
        private var _bmp:Bitmap;
        
        private var sqrtLUT:LUT;
        private var sinLUT:LUT;
        private var cosLUT:LUT;

        /* pixel vector*/                 
        public  var _pixels:Vector.<uint>; 
  
        private var stageRect:Rectangle;
        private var zeroPoint:Point = new Point();
        private var blurFilter:BlurFilter = new BlurFilter(3,3,3);
               
        public function LissajousCurve()
        {
            if (stage) 
            {
                 init(null) 
            }
            else
            {
                addEventListener(Event.ADDED_TO_STAGE, init, false, 0, true);
            }
        }
        
        private function init(e:Event):void
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            
            
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.frameRate = 60;
            stage.fullScreenSourceRect = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight);
            
            stageRect = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight);
            
            start();
        }
        
        private function start():void
        {
            //Wonderfl.capture_delay (15);
            
             _bmd = new BitmapData( stage.stageWidth, stage.stageHeight, true, 0xffffffff);

             _pixels = _bmd.getVector( stageRect )
             _pixels.fixed = false
            
            _bmp = new Bitmap(_bmd);
            _bmp.smoothing = true;
            
            
            addChild(_bmp);
            addChild( new Stats() );
        
            sqrtLUT =  new LUT(2, 200000, Math.sqrt);
            sinLUT =  new LUT(2, LUT.TWO_PI, Math.sin);
            cosLUT =  new LUT(2, LUT.TWO_PI, Math.cos);
                                
            stage.addEventListener(MouseEvent.CLICK, click, false, 0, true);
            stage.addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
        }
        
        private function click(e:MouseEvent):void
        {
            stage.removeEventListener(Event.ENTER_FRAME, loop);
            
            _bmd.fillRect( stageRect, 0xffffffff);
            _pixels = _bmd.getVector( stageRect )
            
            resetFunc();
            
            stage.addEventListener(Event.ENTER_FRAME, loop,false, 0, true);
        }
        
        
        /**
         *    "Extremely Fast Line Algorithm"
         *    @author     Po-Han Lin (original version: http://www.edepot.com/algorithm.html)
         *    @author     Simo Santavirta (AS3 port: http://www.simppa.fi/blog/?p=521) 
         *    @author   Andrea Bovo - added setVector lookup
         */
         
        private function efla( pixels:Vector.<uint>,  x:int, y:int, x2:int, y2:int, color:uint): void
        {
            var shortLen:int = y2-y;
            var longLen:int = x2-x;
            var yLonger:Boolean
            var index:uint =0  
            
            if ( (shortLen ^ (shortLen >> 31)) - (shortLen >> 31) > (longLen ^ (longLen >> 31)) - (longLen >> 31))
            {
                shortLen ^= longLen;
                longLen ^= shortLen;
                shortLen ^= longLen;
                yLonger = true;
            }
            else
            {
                yLonger = false;
            }
 
            var inc:int = longLen < 0 ? -1 : 1;
            
            var i:int = 0
            var multDiff:Number = longLen == 0 ? shortLen : shortLen / longLen;
            
            if (yLonger)
            {
                for (i = 0; i != longLen; i += inc)
                {
                  //bmd.setPixel(x + i*multDiff, y+i, color);
                  pixels[  xyToOff(x + i*multDiff, y+i, WIDTH)  ] = color
                }
            }
            else
            {
                for (i = 0; i != longLen; i += inc)
                {
                   //bmd.setPixel(x+i, y+i*multDiff, color);
                   pixels[ xyToOff( x+i, y+i*multDiff, WIDTH)] = color
                }
            }
       }
        
       private function xyToOff( x:int , y:int , width:int ): int {
            return (y * width) + x;
        }
        
       
       
       
        private function resetFunc():void
        {
            _points.splice(0, _points.length);
            _dist = 0;
            
            _angleX = Math.random() * Math.PI / 2;
            _angleY = - Math.random() * Math.PI / 4;
            _speedX = Math.random() * 0.1 - 0.05;
            _speedY = Math.random() * 0.1 - 0.05;
        }
        
                
        private function loop(e:Event):void
        {            
            var p0:Node = new Node();
            var p1:Node = new Node();
            var dx:Number;
            var dy:Number;
            var color:uint = 0xff000000;
            var i:int = 0;
            var len:int = _points.length;
            
            p1.x = (WIDTH/2) * (1 + cosLUT.valTrig(_angleX) )
            p1.y = (HEIGHT/2) *(1 + sinLUT.valTrig(_angleY) )
            
            _angleX += _speedX;
            _angleY += _speedY;
            _speedX += Math.random() * 0.01 - 0.005;
            _speedY += Math.random() * 0.01 - 0.005;
            _speedX *= 0.995;
            _speedY *= 0.995;
            
            _bmd.lock()
            
            for (i = 0; i < len; i++)
            {
                p0 = _points[i];                     
                
                dx = p0.x - p1.x;;
                dy = p0.y - p1.y;
                
                _dist = sqrtLUT.val( dx * dx + dy * dy ) ;
                
                if (_dist < 1) 
                {
                    return
                }
                else
                if (_dist < 40)
                {
                    var alpha:uint = (color >> 24) & 0xff;
                    var tone:uint  = (color >> 24) & 0xff;
                    
                    var min:Number = Math.min(alpha - _dist / 80, 0xff);
                    var max:Number = Math.max(117, min);
                    
                    alpha = (alpha < 0xff) ? max : min;
                    
                    tone = tone < 255 ? tone - (_dist * 0.48) : 255 - (_dist * 0.78);
                    
                    color = (alpha << 24) | (tone << 16) | (tone << 8) | tone;
                    
                    efla( _pixels, p0.x, p0.y, p1.x, p1.y, color);
                    
                }
            } 
            _points.push(p1);
            
            _bmd.setVector( stageRect, _pixels);
            _bmd.applyFilter( _bmd, stageRect, zeroPoint, blurFilter);
            _bmd.unlock();
            
        }
    }    
    
    
}


class Node
{
    public var x:Number;
    public var y:Number;
        
    public function Node():void
    {
            
    }
}


/*********************************************************************************************************/




/**
*   A generic lookup table useful for caching the results of a function
*   @author Jackson Dunstan
*/
class LUT
{
        /** 2 * PI, the number of radians in a circle*/
        public static const TWO_PI:Number = 2.0 * Math.PI;
 
        /** The static TWO_PI cached as a non-static field*/
        private const TWO_PI:Number = LUT.TWO_PI;
        
        /** Table of function values*/
        public var table:Vector.<Number>;
 
        /** 10^decimals of precision*/
        public var pow:Number;
 
        /**
        *   Make the look up table
        *   @param max Maximum value to cache
        *   @param numDigits Number of digits places of precision
        *   @param func Function to call to generate stored values.
        *               Must be valid on [0,max).
        *   @throws Error If func is null or invalid on [0,max)
        */
        public function LUT(numDigits:uint, max:Number, func:Function)
        {
            var pow:Number = this.pow = Math.pow(10, numDigits);
            var round:Number = 1.0 / pow;
            var len:uint = 1 + max*pow;
            var table:Vector.<Number> = this.table = new Vector.<Number>(len);
 
            var val:Number = 0;
            for (var i:uint = 0; i < len; ++i)
            {
                table[i] = func(val);
                val += round;
            }
        }
 
        /**
        *   Look up the value of the given input
        *   @param val Input value to look up the value of
        *   @return The value of the given input
        */
        public function val(val:Number): Number
        {
            return this.table[ int(val*this.pow) ];
        }
        
         /**
        *   Look up the value of the given number of radians
        *   @param radians Radians to look up the value of
        *   @return The value of the given number of radians
        */
        public function valTrig(radians:Number): Number
        {
            return radians >= 0
                ? this.table[int((radians%this.TWO_PI)*this.pow)]
                : this.table[int((TWO_PI+radians%this.TWO_PI)*this.pow)];
        }
 
        /**
        *   Look up the value of the given number of radians
        *   @param radians Radians to look up the value of. Must be positive.
        *   @return The sine of the given number of radians
        *   @throws RangeError If radians is not positive
        */
        public function valTrigPositive(radians:Number): Number
        {
            return this.table[int((radians%this.TWO_PI)*this.pow)];
        }
 
        /**
        *   Look up the value of the given number of radians
        *   @param radians Radians to look up the value of. Must be on (-2pi,2pi).
        *   @return The value of the given number of radians
        *   @throws RangeError If radians is not on (-2pi,2pi)
        */
        public function valTrigNormalized(radians:Number): Number
        {
            return radians >= 0
                ? this.table[int(radians*this.pow)]
                : this.table[int((this.TWO_PI+radians)*this.pow)];
        }
 
        /**
        *   Look up the value of the given number of radians
        *   @param radians Radians to look up the value of. Must be on [0,2pi).
        *   @return The value of the given number of radians
        *   @throws RangeError If radians is not on [0,2pi)
        */
        public function valTrigNormalizedPositive(radians:Number): Number
        {
            return this.table[int(radians*this.pow)];
        }
        
    }