home *** CD-ROM | disk | FTP | other *** search
/ Carousel Volume 2 #1 / carousel.iso / mactosh / hc / xcmd_fra.sit / fractal.c next >
Text File  |  1987-10-14  |  4KB  |  195 lines

  1. /*
  2.     fractal xcmd v0.3 -- Doug Felt, Oct 14, 1987
  3.     
  4.     This draws a fractal on the screen.  Not to the card, yet.  Function is
  5.     f(z) = z * z + c, julia set mapped to 4 patterns.
  6.     
  7.     Format:
  8.          Fractal seed.h seed.v [res = 8 [limit = 32 [lock = 0]]]
  9.          
  10.     seed is the complex constant c (v imaginary)
  11.     res is the number of pixels on a side for the point to plot 
  12.     limit is the max number of iterations (best between 16 & 128, multiple of 4),
  13.        lower limit means most complex regions of the fractal are white
  14.     if lock is 0, pressing the mouse will immediately stop the drawing, otherwise
  15.       pressing the mouse has no effect and drawing can only be stopped by reboot or
  16.       fancy macsbug work.
  17.    
  18.     Doug Felt, AIR/CAT Project
  19.     duggie@jessica.stanford.edu
  20.  
  21.     
  22.     To compile and link in MPW C:
  23.  
  24.     C -q2 Fractal.c
  25.     link -sn Main=Fractal -sn STDIO=Fractal ╢
  26.          -sn INTENV=Fractal -rt XCMD=104 ╢
  27.          -m FRACTAL Fractal.c.o "{CLibraries}CRunTime.o" ╢
  28.          -o HyperCommands
  29. */
  30.  
  31. #include <Types.h>
  32. #include <Memory.h>
  33. #include <OSUtils.h>
  34. #include <QuickDraw.h>
  35. #include <Events.h>
  36. #include <HyperXCmd.h>
  37. pascal void Debugger() extern 0xA9FF;   
  38.  
  39.  
  40. pascal void Fractal(paramPtr)
  41. XCmdBlockPtr paramPtr;
  42. {
  43. extended ParamToExt();
  44. long ParamToNum();
  45. int nolock,res,hsize,vsize,i,j,iter,limit,rbaseh;
  46. extended rat,seedh,seedv,valh,valv,temp,basev,baseh,hsq,vsq;
  47. extended real2,realn2,real100;
  48. long fake256,fake171,fake2,fake100;
  49. Rect r;
  50. struct _aPattern {
  51.     long long1,long2;
  52.     } pats[4];
  53.  
  54.     if (paramPtr->paramCount<2)
  55.         return;
  56.  
  57.     pats[0].long1 = 0;
  58.     pats[0].long2 = 0;
  59.     pats[1].long1 = 0xaa005500;
  60.     pats[1].long2 = 0xaa005500;
  61.     pats[2].long1 = 0x55ffaaff;
  62.     pats[2].long2 = 0x55ffaaff;
  63.     pats[3].long1 = 0xffffffff;
  64.     pats[3].long2 = 0xffffffff;
  65.     
  66.     res = 8;
  67.     limit = 32;
  68.     nolock = 1;
  69.     
  70.     seedh = ParamToExt(paramPtr,0);
  71.     seedv = ParamToExt(paramPtr,1);
  72.     if (paramPtr->paramCount>2) {
  73.         res = ParamToNum(paramPtr,2);
  74.         if (res <= 0)
  75.             res = 1;
  76.     }
  77.     
  78.     if (paramPtr->paramCount>3) {
  79.         limit = ParamToNum(paramPtr,3);
  80.         if (limit<4) 
  81.             limit = 4;
  82.     }
  83.     
  84.     if (paramPtr->paramCount>4) {
  85.         nolock = !ParamToNum(paramPtr,4);
  86.     };
  87.     
  88.         
  89.     /* map screen onto -2 to 2 range */
  90.     
  91.     /* 0,0 is at 512/2, 342/2 = 256,171 */
  92.     
  93.     /* gridding to res requires that I find out how many boxes wide and tall
  94.        the image is, and map each box onto a value in r2.  then i iterate over
  95.        all the boxes calling the function until the x or y exceeds some limit.
  96.        then i map the number of iterations into a 'color' */
  97.        
  98.     /* since we don't have a global data area for extended constants to live in,
  99.        use longs and fake the compiler into making the correct SANE calls to 
  100.        build the extended values.  Is there a better way (besides using Pascal!) */
  101.     
  102.     fake256 = 256;
  103.     fake171 = 171;
  104.     fake2 = 2;
  105.     fake100 = 100;
  106.     
  107.     hsize = (fake256/res)+1;            /* integer math truncates */
  108.     vsize = (fake171/res)+1;
  109.     real100 = fake100;                    /* fools the not-too-bright compiler. */
  110.     real2 = fake2;
  111.     realn2 = -fake2;
  112.     rat = real2/hsize;                    /* reals intermediate result because of real2 */
  113.     
  114.     rbaseh = 256-hsize*res;
  115.     r.top = 171-vsize*res;
  116.     r.bottom = r.top + res;
  117.     basev = realn2*fake171/fake256;        /* center it */
  118.     
  119.     for (i=-vsize; i<vsize; ++i) {
  120.         r.left = rbaseh;
  121.         r.right = r.left + res;
  122.         baseh = realn2;
  123.         for (j=-hsize; j<hsize; ++j) {
  124.             valh = baseh;
  125.             valv = basev;
  126.             iter = 0;
  127.             do {
  128.                 hsq = valh * valh;
  129.                 vsq = valv * valv;
  130.                 temp = hsq - vsq + seedh;
  131.                 valv = real2*valh*valv + seedv;
  132.                 valh = temp;
  133.                 ++iter;
  134.             } while ((hsq+vsq<real100) && (iter<limit));
  135.  
  136.             PenPat(&pats[iter & 0x03]);
  137.             PaintRect(&r);
  138.  
  139.             r.left += res;
  140.             r.right += res;
  141.             baseh += rat;
  142.             if (nolock && Button())
  143.                     return;
  144.         }
  145.         r.top += res;
  146.         r.bottom += res;
  147.         basev += rat;
  148.     }
  149. }
  150.  
  151.  
  152. long ZeroToNum(paramPtr,zeroStr)
  153. XCmdBlockPtr paramPtr;
  154. char *zeroStr;
  155. {
  156. Str255 str;
  157.  
  158.     ZeroToPas(paramPtr,zeroStr,&str);
  159.     return StrToNum(paramPtr,&str);
  160. }
  161.  
  162. long ParamToNum(paramPtr,index)
  163. XCmdBlockPtr paramPtr;
  164. int index;
  165. {
  166. long ZeroToNum();
  167.  
  168.     return ZeroToNum(paramPtr,*(paramPtr->params[index]));
  169. }
  170.  
  171. extended ZeroToExt(paramPtr,zeroStr)
  172. XCmdBlockPtr paramPtr;
  173. char *zeroStr;
  174. {
  175. Str255 str;
  176. extended res;
  177.  
  178.     ZeroToPas(paramPtr,zeroStr,&str);
  179.     StrToExt(paramPtr,&str,&res);
  180.     return res;
  181. }
  182.  
  183. extended ParamToExt(paramPtr,index)
  184. XCmdBlockPtr paramPtr;
  185. int index;
  186. {
  187. extended ZeroToExt();
  188.  
  189.     return ZeroToExt(paramPtr,*(paramPtr->params[index]));
  190. }
  191.  
  192.  
  193. #include <XCmdGlue.inc.c>
  194.  
  195.