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

FFT + Fluid Solver

Get Adobe Flash player
by architectural.synthesis 18 Aug 2012
  • Related works: 1
  • Talk

    bradsedito at 24 Jun 2012 04:36
    Holy crap this is brilliant. and simple. I don't know how I didn't think of just doing this before - awesome! haha thanks! =)
    Embed
/**
 * Copyright architectural.synthesis ( http://wonderfl.net/user/architectural.synthesis )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/bt7C
 */

// Howto:
// 1. cut and paste everything bellow the "WONDERFL TRACE" line to the end of your script
// 2. insert inittrace(stage); to the constructor of your main class
// 3. done!
package {
    import flash.display.Sprite;
    import flash.events.*;
    import flash.text.TextField;
    
    public class TraceTest extends Sprite {
        
        public function TraceTest() {
            
            //This is all the initialization you need in your main class
            inittrace(stage);
            
            // demonstration
            trace(Math.atan2(1000,0))
        }
        
    }
}

import __AS3__.vec.Vector;




/////  FFT /////

class FFT
{
    public static const FORWARD:Boolean = false;
    public static const INVERSE:Boolean = true;

    private var m_logN:uint = 0;            // log2 of FFT size
    private var m_N:uint = 0;                // FFT size
    private var m_invN:Number;                // Inverse of FFT length

    // Bit-reverse lookup table
    private var m_bitRevLen:uint;            // Length of the bit reverse table
    private var m_bitRevFrom:Vector.<uint>;    // "From" indices for swap
    private var m_bitRevTo:Vector.<uint>;    // "To" indices for swap

    /**
     *
     */
    public function FFT()
    {
    }

    /**
     * Initialize class to perform FFT of specified size.
     *
     * @param    logN    Log2 of FFT length. e.g. for 512 pt FFT, logN = 9.
     */
    public function init(
        logN:uint ):void
    {
        m_logN = logN
        m_N = 1 << m_logN;
        m_invN = 1.0/m_N;

        //    Create the bit-reverse table
        m_bitRevFrom = new Vector.<uint>;
        m_bitRevTo   = new Vector.<uint>;
        for ( var k:uint = 0; k < m_N; k++ )
        {
            var kRev:uint = BitReverse(k,logN);
            if (kRev > k)
            {
                m_bitRevFrom.push(k);
                m_bitRevTo.push(kRev);
            }
        }
        m_bitRevLen = m_bitRevFrom.length;
    }

    /**
     * Performs in-place complex FFT.
     *
     * @param    xRe        Real part of input/output
     * @param    xIm        Imaginary part of input/output
     * @param    inverse    If true (INVERSE), do an inverse FFT
     */
    public function run(
        xRe:Vector.<Number>,
        xIm:Vector.<Number>,
        inverse:Boolean = false ):void
    {
        var numFlies:uint = m_N >> 1;    // Number of butterflies per sub-FFT
        var span:uint = m_N >> 1;        // Width of the butterfly
        var spacing:uint = m_N;            // Distance between start of sub-FFTs
        var wIndexStep:uint = 1;         // Increment for twiddle table index

        // For each stage of the FFT
        for ( var stage:uint = 0; stage < m_logN; ++stage )
        {
            // Compute a multiplier factor for the "twiddle factors".
            // The twiddle factors are complex unit vectors spaced at
            // regular angular intervals. The angle by which the twiddle
            // factor advances depends on the FFT stage. In many FFT
            // implementations the twiddle factors are cached, but because
            // vector lookup is relatively slow in ActionScript, it's just
            // as fast to compute them on the fly.
            var wAngleInc:Number = wIndexStep * 2.0*Math.PI/m_N;
            if ( inverse == false ) // Corrected 3 Aug 2011. Previously this condition was backwards!
                wAngleInc *= -1;
            var wMulRe:Number = Math.cos(wAngleInc);
            var wMulIm:Number = Math.sin(wAngleInc);

            for ( var start:uint = 0; start < m_N; start += spacing )
            {
                var top:uint    = start;
                var bottom:uint = top + span;

                var wRe:Number = 1.0;
                var wIm:Number = 0.0;

                // For each butterfly in this stage
                for ( var flyCount:uint = 0; flyCount < numFlies; ++flyCount )
                {
                    // Get the top & bottom values
                    var xTopRe:Number = xRe[top];
                    var xTopIm:Number = xIm[top];
                    var xBotRe:Number = xRe[bottom];
                    var xBotIm:Number = xIm[bottom];

                    // Top branch of butterfly has addition
                    xRe[top] = xTopRe + xBotRe;
                    xIm[top] = xTopIm + xBotIm;

                    // Bottom branch of butterly has subtraction,
                    // followed by multiplication by twiddle factor
                    xBotRe = xTopRe - xBotRe;
                    xBotIm = xTopIm - xBotIm;
                    xRe[bottom] = xBotRe*wRe - xBotIm*wIm;
                    xIm[bottom] = xBotRe*wIm + xBotIm*wRe;

                    // Update indices to the top & bottom of the butterfly
                    ++top;
                    ++bottom;

                    // Update the twiddle factor, via complex multiply
                    // by unit vector with the appropriate angle
                    // (wRe + j wIm) = (wRe + j wIm) x (wMulRe + j wMulIm)
                    var tRe:Number = wRe;
                    wRe = wRe*wMulRe - wIm*wMulIm;
                    wIm = tRe*wMulIm + wIm*wMulRe
                }
            }

            numFlies >>= 1;     // Divide by 2 by right shift
            span >>= 1;
            spacing >>= 1;
            wIndexStep <<= 1;      // Multiply by 2 by left shift
        }

        // The algorithm leaves the result in a scrambled order.
        // Do bit-reversal to unscramble the result.
        for ( var k:uint = 0; k < m_bitRevLen; k++ )
        {
            var brFr:uint = m_bitRevFrom[k];
            var brTo:uint = m_bitRevTo[k];
            var tempRe:Number = xRe[brTo];
            var tempIm:Number = xIm[brTo];
            xRe[brTo] = xRe[brFr];
            xIm[brTo] = xIm[brFr];
            xRe[brFr] = tempRe;
            xIm[brFr] = tempIm;
        }

        //    Divide everything by n for inverse
        if ( inverse )
        {
            for ( k = 0; k < m_N; k++ )
            {
                xRe[k] *= m_invN;
                xIm[k] *= m_invN;
            }
        }
    }

    /**
     * Do bit reversal of specified number of places of an int
     * For example, 1101 bit-reversed is 1011
     *
     * @param    x        Number to be bit-reverse.
     * @param    numBits    Number of bits in the number.
     */
    private function BitReverse(
        x:uint,
        numBits:uint):uint
    {
        var y:uint = 0;
        for ( var i:uint = 0; i < numBits; i++)
        {
            y <<= 1;
            y |= x & 0x0001;
            x >>= 1;
        }
        return y;
    }
}

/////  WONDERFL TRACE /////

import flash.display.Sprite;
import flash.display.Stage;
import flash.text.TextField;
import flash.text.TextFormat;


function inittrace(s:Stage):void
{
    WTrace.initTrace(s);
}

//global trace function
var trace:Function;

//wtreace class
class WTrace
{
        private static var FONT:String = "Fixedsys";
        private static var SIZE:Number = 12;
        private static var TextFields:Array = [];
        private static var trace_stage:Stage;
        
        public static function initTrace(stg:Stage):void
        {
            trace_stage = stg;
            trace = wtrace;
        }
        
        private static function scrollup():void
        {
            // maximum number of lines: 100
            if (TextFields.length > 100) 
            {
                var removeme:TextField = TextFields.shift();
                trace_stage.removeChild(removeme);
                removeme = null;
            }
            for(var x:Number=0;x<TextFields.length;x++)
            {
                (TextFields[x] as TextField).y -= SIZE*1.2;
            }
        }
    
        public static function wtrace(... args):void
        {
        
            var s:String="";
            var tracefield:TextField;
            
            for (var i:int;i < args.length;i++)
            {
                // imitating flash:
                // putting a space between the parameters
                if (i != 0) s+=" ";
                s+=args[i].toString();
            }
            

            tracefield= new TextField();
            tracefield.autoSize = "left";
            tracefield.text = s;
            tracefield.y = trace_stage.stageHeight - 20;

            var tf:TextFormat = new TextFormat(FONT, SIZE);
            tracefield.setTextFormat(tf);
            trace_stage.addChild(tracefield);
            scrollup();                      
            TextFields.push(tracefield);
            
        }
}