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

shenu

@author Andrea Bovo spleen666@gmail.com

added 

sin/cos inline optimizations
http://lab.polygonal.de/2007/07/18/fast-and-accurate-sinecosine-approximation/

sqrt LUT
http://jacksondunstan.com/articles/1217#more-1217
/**
 * Copyright lespleen ( http://wonderfl.net/user/lespleen )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/AjSo
 */

/**
* forked from codeonwort's forked from: transition
* forked from Nyarineko's transition
*
*@author Andrea Bovo spleen666@gmail.com
*
*@see http://lab.polygonal.de/2007/07/18/fast-and-accurate-sinecosine-approximation/
*@see http://jacksondunstan.com/articles/1217#more-1217
*/

package
{
    import flash.text.engine.SpaceJustifier;

    import flash.geom.Point;
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Shape;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.geom.Rectangle;
    import flash.display.Graphics;
    import flash.filters.BlurFilter
   
    import net.hires.debug.Stats;
   
    [SWF(width = "465", height = "465", backgroundColor = "0xffffff", frameRate = "60")]
    
    public class Main extends Sprite
    {
        //private const TF:Boolean = false; //transition mode
        private const M_WIDTH:Number = 465;
        private const M_HEIGH:Number = 465;
        private const OX:Number = 465 / 2;
        private const OY:Number = 465 / 2;
        private const V:Number = 2;
        private const OBJ_MAX:Number = 50;
        private var max:uint = 50;
        private var amax:uint = 0;
        private var _canvas:BitmapData;
        private var dst:BitmapData
        private var _bmp:Bitmap;
        private var _sp:Sprite;
        private var _sr:Number;
        private var _vr:Number;
        private var first:Particle;

        private var zero:Point = new Point
        private var blur:BlurFilter = new BlurFilter(2, 2, 3);
        
        private var _pixels:Vector.<uint>;           
        
        private var sqrtLUT:LUT;
                    
        public function Main()
        {
            _sp = new Sprite();
            
            _canvas = new BitmapData(M_WIDTH, M_HEIGH, true, 0x00000000);
            _pixels = _canvas.getVector( _canvas.rect );
         
            sqrtLUT = new LUT(2, 200000, Math.sqrt);
         
            _bmp = new Bitmap(_canvas);
            _bmp.smoothing = true;
            _bmp.blendMode = "invert";
            
            _bmp.x = -M_WIDTH / 2;
            _bmp.y = -M_HEIGH / 2;
     
            _sp.addChild(_bmp);
            _sp.x = M_WIDTH / 2;
            _sp.y = M_HEIGH / 2;
     
            addChild(_sp);
            addChild( new Stats())
            
            init();
            
            stage.addEventListener(MouseEvent.CLICK,click,false,0,true);
            stage.addEventListener(Event.ENTER_FRAME,loop,false,0,true);
        }
        
     
        private function init():void
        {
            var p:Particle;
            
                        
            _sr = 1;
            _vr = 0.00005;
            
            first = new Particle();
            
            p = first;
            
            for(var i:uint = 0;i < max;i++)
            {
                
                p.ang = i * 360 / max;
                p.vang = 1;
                p.r = 10;
                p.vr = 0;
                p.x = OX;
                p.y = OY;
                
                if(i != max - 1)
                {
                    p.next = new Particle();
                    p = p.next;
                }
            }
        }
        
        
        private function loop(e:Event):void
        {
            update();
        }
        
        private function click(e:MouseEvent):void
        {
            _canvas.lock();
            _canvas.fillRect( _canvas.rect, 0xFFFFFF);
            _pixels = _canvas.getVector( _canvas.rect );
            _canvas.unlock();
            
             init();
        }
        
        private function update():void 
        {
            var sh:Shape = new Shape();
            var g:Graphics = sh.graphics;
            
            var ang:Number;
            var ax:Number;
            var ay:Number;
            var rr:Number;
            var anga:Number;
            var px:Number;
            var py:Number;
            var r:Number;
            var ran:Number;
            var p:Particle = first;
            var cnt:uint = 0;
            
            _canvas.lock();  
                      
            while( p )
            {
                
                g.lineStyle(p.thickness, p.color, p.alpha);
                cnt++;
                
                if(p.r > 400)
                {
                    p = p.next;
                    continue;
                }
                
                ran =  Math.random();
                
                if(ran < 0.1){
                    p.vang = 0;
                    p.vr = V;
                }
                else 
                if(ran < 0.2){
                    p.vang = -V;
                    p.vr = 0;
                }
                else 
                if(ran < 0.3)
                {
                    p.vang = V;
                    p.vr = 0;
                }
                else 
                if(ran < 0.304 && amax < OBJ_MAX)
                {
                    var newP:Particle = new Particle();
                    newP.ang = p.ang;
                    
                    if(p.vang == 0) 
                        newP.vang = 0;
                    else 
                        newP.vang = (Math.random() < 0.5)?-1:1;
                    
                    newP.r = p.r;
                    
                    
                    if(p.vang == 0) 
                        newP.vr = 1;
                    else 
                        newP.vr = 0;
                        
                    newP.x = p.x;
                    newP.y = p.y;
                    newP.next = p.next;
                    
                    p.next = newP;
                }
                
                r = p.ang + p.vang;
                p.r = p.r + p.vr;
                
                var sin:Number;
                var cos:Number;
                
                                
                ang = Math.PI/180 * r;
                sin = 0.0
                cos = 0.0
                //always wrap input angle to -PI..PI
                if (ang < -3.14159265) ang += 6.28318531;
                else 
                if (ang > 3.14159265) ang -= 6.28318531;
                //compute sine
                if (ang < 0) {
                  sin = 1.27323954 * ang + .405284735 * ang * ang;
                  if (sin < 0) sin = .225 * (sin * -sin - sin) + sin;
                  else sin = .225 * (sin * sin - sin) + sin;
                } else {
                  sin = 1.27323954 * ang - 0.405284735 * ang * ang;
                  if (sin < 0) sin = .225 * (sin * -sin - sin) + sin;
                  else sin = .225 * (sin * sin - sin) + sin;
                }
                ay = p.r * sin;
                
                //compute cosine: sin(x + PI/2) = cos(x)
                ang += 1.57079632;
                if (ang > 3.14159265) ang -= 6.28318531;
                if (ang < 0) {
                  cos = 1.27323954 * ang + 0.405284735 * ang * ang
                  if (cos < 0) cos = .225 * (cos * -cos - cos) + cos;
                  else cos = .225 * (cos * cos - cos) + cos;
                } else {
                  cos = 1.27323954 * ang - 0.405284735 * ang * ang;
                  if (cos < 0) cos = .225 * (cos * -cos - cos) + cos;
                  else cos = .225 * (cos * cos - cos) + cos;
                }
                ax = p.r * cos
                
                //
                rr = sqrtLUT.val(ax * ax + ay * ay);
                
                anga = Math.PI/180 * (r - (r - p.ang) / 2);
                sin = 0.0
                cos = 0.0
                //always wrap input angle to -PI..PI
                if (anga < -3.14159265) anga += 6.28318531;
                else if (anga > 3.14159265) anga -= 6.28318531;
                //compute sine
                if (anga < 0) {
                  sin = 1.27323954 * anga + .405284735 * anga * anga;
                  if (sin < 0) sin = .225 * (sin * -sin - sin) + sin;
                  else sin = .225 * (sin * sin - sin) + sin;
                } else {
                  sin = 1.27323954 * anga - 0.405284735 * anga * anga;
                  if (sin < 0) sin = .225 * (sin * -sin - sin) + sin;
                  else sin = .225 * (sin * sin - sin) + sin;
                }
                py = rr * sin
              
                //compute cosine: sin(x + PI/2) = cos(x)
                anga += 1.57079632;
                if (anga > 3.14159265) anga -= 6.28318531;
                if (anga < 0) {
                  cos = 1.27323954 * anga + 0.405284735 * anga * anga
                  if (cos < 0) cos = .225 * (cos * -cos - cos) + cos;
                  else cos = .225 * (cos * cos - cos) + cos;
                } else {
                  cos = 1.27323954 * anga - 0.405284735 * anga * anga;
                  if (cos < 0) cos = .225 * (cos * -cos - cos) + cos;
                  else cos = .225 * (cos * cos - cos) + cos;
                }
                px = rr * cos
                                
               g.moveTo(p.x,p.y);
               g.curveTo(px+OX, py+OY,ax+OX, ay+OY);
               
               //g.lineTo(ax+OX, ay+OY);
               //eflaVec( _pixels, M_WIDTH, p.x, p.y,  px+OX, py+OY, 0x0);
                 
                p.x = ax+OX;
                p.y = ay+OY;
                
                p.ang = r;
                
                p = p.next;
            }
            
           /** if(_sr < 400 && TF){
                g.beginFill(0xFFFFFF);
                if(_vr < 8) _vr += _vr/30;
                _sr = _sr + _vr;
                g.drawCircle(OX,OY,_sr);
                g.endFill();
            }*/
            
            //_canvas.setVector( _canvas.rect, _pixels);
            
            
           _canvas.draw(sh);
           
           //_canvas.applyFilter(_canvas, _canvas.rect, zero, blur)
            
           var tmp:BitmapData = _canvas.clone()
           
           //_canvas.draw(tmp, null, null, "add")
           
           //
           //dst.draw(temp, null, null, "screen")
           
           _canvas.unlock();
                      
           tmp.dispose()
           
            g = null;
            sh = null;
            
            amax = cnt;
        }
        
        
         /**
         *    "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 eflaVec( pixels:Vector.<uint>, width:int,  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;
        }
        
    }
  
}

class Particle
{
    public var ang:Number;
    public var vang:Number;
    public var r:Number;
    public var vr:Number;
    public var x:Number;
    public var y:Number;
    public var next:Particle;
    
    public var alpha:Number = 0.3 + Math.random()*0.2
    public var thickness:uint = Math.random() * 4
    private var from:uint = Math.random() * 0xffffff
    private var to:uint = Math.random() * 0xffffff
    private var prog:Number = 0
    
    public function get color():uint {
        
        prog += 0.05
        
        if(prog > 1){
            prog = 0
            from = to
            to = Math.random() * 0xffffff
        }
        
        return interpolate(0x0, 0xff0000, prog)
    }

}


/**
*   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)];
        }
        
   }



/** interpolate color **/
internal function interpolate(from:uint, to:uint, t:Number):uint 
{
    var r1:uint = (from >> 16) & 0xFF, g1:uint = (from >> 8) & 0xFF, b1:uint = from & 0xFF
    var r2:uint = (to >> 16) & 0xFF, g2:uint = (to >> 8) & 0xFF, b2:uint = to & 0xFF
    var r:uint = r1+(r2-r1)*t, g:uint = g1+(g2-g1)*t, b:int = b1+(b2-b1)*t
    
    return (r<<16) | (g<<8) | b
}