Mandelbrot Explorer

From Second Life Wiki
Revision as of 04:27, 19 June 2008 by Babbage Linden (talk | contribs) (New page: // Mandelbrot Explorer by Babbage Linden // // Interactive Fractal Explorer Demo // // Add this script to a screen made from 245 linked prisms each manipulated to show 5 faces in one direc...)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

// Mandelbrot Explorer by Babbage Linden // // Interactive Fractal Explorer Demo // // Add this script to a screen made from 245 linked prisms each manipulated to show 5 faces in one direction // to form a 35x35 pixel display. When rezzed or reset the object will calculate and display a mandelbrot set. // Clicking on the display will centre the view on the clicked prim and zoom in, allowing the fractal to be // explored. To return to the initial image either reset the script, or take and rez the object. // // Available under the Creative Commons Attribution-ShareAlike 2.5 license // http://creativecommons.org/licenses/by-sa/2.5/

list faces = [3,7,4,6,1];

integer xsize=35; integer ysize=35; integer numfaces=5; integer fwidth=7;

integer linkNumToX(integer linkNum) {

   integer result = ((linkNum - 1) % fwidth) * numfaces + (numfaces / 2);
   return result;

}

integer linkNumToY(integer linkNum) {

   integer result = ((linkNum - 1) / fwidth);
   return result;

}

setpixel(integer x, integer y, vector colour) {

   integer face = (y*xsize) + x;
   integer linknum = face/numfaces;
   integer primface = face - (linknum*5); 
   llSetLinkColor(linknum + 1, colour, llList2Integer(faces,primface));

}

mandlebrot(float startx, float starty, float zoom, integer width) {

   integer height = width;
   integer i;
   integer m = 50; // Max iterations.
   integer isOverLimit = FALSE;
   float Zr = 0.0;
   float Zi = 0.0;
   float Cr = 0.0;
   float Ci = 0.0;
   float Tr;
   float Ti;
   float limit2 = 4.0;

   integer y;
   for(y = 0; y < height; y++) 
   {
       integer x;
        for(x = 0; x < width; x++)
        {
           Zr = 0.0; Zi = 0.0;
           Cr = (2.0 * (x + (startx / zoom)) / width - 1.5) * zoom;
           Ci = (2.0 * (y + (starty / zoom)) / height - 1.0) * zoom;
    
           i = 0;
           do {
              Tr = Zr*Zr - Zi*Zi + Cr;
              Ti = 2.0*Zr*Zi + Ci;
              Zr = Tr; Zi = Ti;
              isOverLimit = Zr*Zr + Zi*Zi > limit2;
           } while (!isOverLimit && (++i < m));
           
           // Generate colour for each possible iteration.
           // First fill r, then overflow in to g, then b.
           vector colour = <0,0,0>;
           if(i < m)
           {
               integer step = m / 3;
               float fstep = step;
               
               if(i > 0)
               {
                   colour.x = i / fstep;
                   i -= step;
               }
               if(i > 0)
               {
                   colour.y = i / fstep;
                   i -= step;
               }
               if(i > 0)
               {
                   colour.z = i / fstep;
                   i -= step;
               }
           }
           setpixel(x, y, colour);    
       }
   }

}

float gZoom = 1.0; float gMinX = 0; float gMinY = 0;

default {

   on_rez(integer param)
   {
       // Draw initial fractal image.
       mandlebrot(gMinX, gMinY, gZoom, 35);
   }
   
   state_entry()
   {        
       // Draw initial fractal image.
       mandlebrot(gMinX, gMinY, gZoom, 35);
   }
   
   touch_start(integer num)
   {
       // Convert link number in to screen space.
       float dx = linkNumToX(llDetectedLinkNumber(0));
       float dy = linkNumToY(llDetectedLinkNumber(0));
               
       // Make dx and dy relative to centre.
       dx -= (xsize / 2);
       dy -= (ysize / 2);
       
       // Adjust gMinX and gMinY by x and y.
       gMinX += dx * gZoom;
       gMinY += dy * gZoom;
       
       // Calculate Mandelbrot and increase zoom.
       mandlebrot(gMinX, gMinY, gZoom, 35);
       gZoom *= 0.9;
   }

}