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

Perlin Particles + HSV transform [optimized code]

Fixed the mistake. My bad. Haha.
Get Adobe Flash player
by bradsedito 02 Mar 2012
/**
 * Copyright bradsedito ( http://wonderfl.net/user/bradsedito )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/gJWy
 */





package 
{
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.filters.BlurFilter;
    import flash.geom.ColorTransform;
    import flash.geom.Point;
    import flash.geom.Rectangle;
    import flash.utils.getTimer;
    import flash.utils.Timer;
    import com.greensock.*;
    import com.greensock.easing.*;
    import net.hires.debug.Stats;

    [SWF(width=465, height=465, backgroundColor=0x000000,frameRate=60)]


    public class PerlinParticles extends Sprite 
    {
        private const _stageW:uint = stage.stageWidth;
        private const _stageH:uint = stage.stageHeight;
        private const _point:Point = new Point(0,0);
        private const _particlesNum:uint = 6000;
        private const _blurFilter:BlurFilter = new BlurFilter(16,16,4);//16,16,4 hurts much, we know!
        private const _numOct:uint = 4;
        private const _perlinSize:uint = 32;
        private const _ratioX:Number = (_stageW/_perlinSize)/_stageW;
        private const _ratioY:Number = (_stageH/_perlinSize)/_stageH;
        private var _perlinData:BitmapData = new BitmapData(_perlinSize,_perlinSize,false,0x000000);
        private var _perlinBitmap:Bitmap = new Bitmap(_perlinData);
        private var _renderData:BitmapData = new BitmapData(_stageW,_stageH,false,0x000000);
        private var _renderRect:Rectangle = new Rectangle(0,0,_stageW,_stageH);
        private var _renderBitmap:Bitmap = new Bitmap(_renderData);
        private var _offsets:Array = new Array;
        private var _freq:Vector.<uint> = new Vector.<uint>(_numOct*2,true);
        private var _phase:Vector.<uint> = new Vector.<uint>(_numOct*2,true);
        private var _particles:Vector.<Particle> = new Vector.<Particle>(_particlesNum,true);
        private var _cc:uint = 0;//color control (h from hsv will vary from that)
    
        public function PerlinParticles ()
        {
            addChild(_renderBitmap);
            for (var i:uint=0;i<_particlesNum;++i)
            {
                createParticle(randomNumber(0,_stageW),randomNumber(0,_stageH),0,0,i);
            }
            for (i=0;i<_numOct;++i) 
            {
                _offsets[_offsets.length] = new Point();
                _freq[i>>0] = Math.round(5*Math.random()+1);
                _freq[(i+1)>>0] = Math.round(6*Math.random()+1);
                _phase[i>>0] = Math.round(2*Math.PI*Math.random());
                _phase[(i+1)>>0] = Math.round(2*Math.PI*Math.random());
            }
            _perlinData.perlinNoise(_perlinSize,_perlinSize,_numOct,128,true,false,7,false,_offsets);
            _perlinBitmap.transform.colorTransform = new ColorTransform(1,0,1,1); //remove green channel
            addChild(new Stats());
            addEventListener(Event.ENTER_FRAME, renderDisplay);
        }

        private function renderDisplay(e:Event):void 
        {
            _cc = (++_cc)%720;
            var t:Number = getTimer()*.0001;
            for (var i:uint=0;i<_numOct;++i) 
            {
                _offsets[i].x = _perlinSize*Math.cos(_freq[i>>0]*t+_phase[i>>0]);
                _offsets[i].y = _perlinSize*Math.sin(_freq[(i+1)>>0]*t+_phase[(i+1)>>0]);
            }
            _perlinData.perlinNoise(_perlinSize,_perlinSize,4,128,true,false,7,false,_offsets);
            var color:uint = hsv2rgb(_cc/2,1,.9);
            var r:uint = _particlesNum;
            _renderData.lock();
            _renderData.applyFilter(_renderData,_renderRect,_point,_blurFilter);
            
            while(r--) 
            {
                var v:Particle=_particles[r>>0];
                if (v.y>_stageH || v.y<0 || v.x>_stageW || v.x<0)
                {
                    //setProps(v, {x:randomNumber(0,mouseX),y:randomNumber(0,mouseY),vx:0,vy:0});
                    setProps(v, {x:randomNumber(0,_stageW),y:randomNumber(0,_stageH),vx:0,vy:0});
                }    
                var c:uint = _perlinData.getPixel(v.x*_ratioX,v.y*_ratioY);
                var red:uint = c>>16;
                var blue:uint = c&0xFF;
                v.vx += 48-red;
                v.vy += 48-blue;
                v.x+= v.vx *.005;
                v.y+= v.vy *.005;                
                _renderData.setPixel(v.x,v.y,color);
            }
            _renderData.unlock();    
        }

        private function hsv2rgb(h:Number,s:Number,v:Number):uint
        {
            var i:int = int(h/60);
            var f:Number = h/60-i;
            var p:Number = v*(1-s);
            var q:Number = v*(1-s*f);
            var t:Number = v*(1-s*(1-f));
            
            switch (i) 
            {
                case 0: return v * 0xFF << 16 | t * 0xFF << 8 | p * 0xFF << 0;
                case 1: return q * 0xFF << 16 | v * 0xFF << 8 | p * 0xFF << 0;
                case 2: return p * 0xFF << 16 | v * 0xFF << 8 | t * 0xFF << 0;
                case 3: return p * 0xFF << 16 | q * 0xFF << 8 | v * 0xFF << 0;
                case 4: return t * 0xFF << 16 | p * 0xFF << 8 | v * 0xFF << 0;
                case 5: return v * 0xFF << 16 | p * 0xFF << 8 | q * 0xFF << 0;
            }
            return 0;
        }

        private function createParticle(xx:int,yy:int,vx:Number,vy:Number,i:uint):void 
        {
            var p:Particle=new Particle();
            setProps(p,{x:xx,y:yy,vx:vx,vy:vy});
            _particles[i>>0] = p;
        }
        
        private function setProps(o:*,p:Object):void 
        {
            for (var k:String in p) {o[k]=p[k];}
        }

        private function randomNumber(low:int, high:int):int
        {
            return Math.round(Math.random() * (high - low) + low);
        }
    }
}

import flash.geom.Vector3D;
final class Particle 
{
    public var x:int;
    public var y:int;
    public var z:int;
    public var vx:Number;
    public var vy:Number;
    public var vz:Number;
    public var depth:uint;
    public var location:Vector3D;
}