A Mandelbrot set marks the set of points in the complex plane where z(i) = z(i-1)*z(i-1) + c function does not tend to infinity. These points marked black, but the nearby points, which aren't in the set, is colored according to how fast they tend to infinity. So we can draw very spectacular nutmeats :) And in addition we can zoom in almost continously ( based on the floating-point handling capacity of our platform :).

Complex numbers have two parts: a real and an imaginery part: z = ( r , i )

Addition: z1 + z2 = ( r1 + r2 , i1 + i2 )
Multiplication: z1 * z2 = ( r1 * r2 - i1 * i2 , r1 * i2 + r2 * i1 ).

Based on these operations we can simplify the Mandelbrot function.

z(2) = z(1) * z(1) + c
( z(2)r , z(2)i ) = ( z(1)r , z(1)i )( z(1)r , z(1)i ) + ( cr , ci );
( z(2)r , z(2)i ) = ( z(1)r * z(1)r - z(1)i * z(1)i , z(1)r * z(1)i + z(1)r * z(1)i ) + ( cr , ci );
z(2)r = z(1)r * z(1)r - z(1)i * z(1)i + cr;
z(2)i = z(1)r * z(1)i + z(1)r * z(1)i + ci = 2 * z(1)r * z(1)i + ci;

| zi | > 2 -> we have to stay in the circle with the radius 2

| zi | = sqrt( zr * zr + zi * zi ) > 2;
| zi | exp( 2 ) = zr * zr + zi * zi > 4

Let's translate it to AS3.

`package{        import flash.display.Sprite;    import flash.display.Bitmap;    import flash.display.BitmapData;            public class Mandelbrot extends Sprite    {            // display dimensions, set this as default size        private static var DWTH:Number = 550;        private static var DHTH:Number = 380;                // maximum function cycles        private static var CYCLES:Number = 128;                // the set's bitmapdata        private var bitmapData:BitmapData;                public function Mandelbrot ( )        {                        // creating new bitmap instance            var setBitmap:Bitmap = new Bitmap( );                        // creating new bitmapdata            bitmapData = new BitmapData( DWTH , DHTH , false , 0x000000 );                        // attaching bitmapdata to bitmap            setBitmap.bitmapData = bitmapData;                        // attaching bitmap to display list            addChild( setBitmap );                        // start drawing            drawSet( -2 , 1 , -1 , 1 );                    }                        public function drawSet ( rmin:Number ,     // interval minimum on real axis                                  rmax:Number ,     // interval maximum on real axis                                  imin:Number ,     // interval minimum on imaginary axis                                  imax:Number ):void        {                        // real axis stepping            var rStep:Number = ( rmax - rmin ) / DWTH;            // imaginary axis stepping            var iStep:Number = ( imax - imin ) / DHTH;                        // actual real coordinate            var r:Number;            // actual imaginary coordinate            var i:Number;                        // looping thorugh every display point            for ( var px:int = 0 ; px < DWTH ; px++ )            {                                r = rmin + px * rStep;                                for ( var py:int = 0 ; py < DHTH ; py++ )                {                                        i = imin + py * iStep;                                        var color:uint;                    var cycles:int = getCycles( r , i );                                        // if cycles == CYCLES, the function tends to infinity                    if ( cycles == CYCLES ) color = 0x000000;                    // in not, we generate a greenish colour with bitwise left shit                    else color = cycles << 16 | ( cycles + 50 ) << 8 | cycles;                                        // putting pixel                    bitmapData.setPixel( px , py , color );                                    }                            }                    }                // calculating function cycle number                public function getCycles ( r:Number , i:Number ):uint        {                        var zr:Number = 0;            var zi:Number = 0;                        var cr:Number = r;            var ci:Number = i;                        // z's old values            var ozr:Number = 0;            var ozi:Number = 0;                        // z's old square values            var zrsq:Number = 0;            var zisq:Number = 0;                        for ( var a:int = 0 ; a < CYCLES ; a++ )            {                                zi = ozr * ozi * 2 + ci;                zr = zrsq - zisq + cr;                                zrsq = zr * zr;                zisq = zi * zi;                                ozr = zr;                ozi = zi;                                if ( ( zrsq + zisq ) > 4 ) break;                            }                            return a;                    }            }    }`

Try it. Beautiful, eh? You can make it more detailed, if you set CYCLES higher, but it will also be slower. Check it under attachments.

And what about that bitwise-shift thing? Simple, we needed a 24 bit length colour code from a number under 128. So, i shifted 128 with 16 bits, to the "red" range ( 2(25) - 2(16) ), then i added 50, because i wanted green to be the dominant color, then shifted left with 8 bits to the green range ( 2(15) - 2(8) ), and i left it in the "blue" range, and made a logical "OR" between these values.