home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / virus / ddj0491.zip / FRACTAL.ASC < prev    next >
Text File  |  1991-03-15  |  52KB  |  1,229 lines

  1. _FRACTALS IN THE REAL WORLD_
  2. by Dick Oliver
  3.  
  4. [LISTING 1]
  5.  
  6. /****************************************************************
  7.   SIERP.C -- (C) 1990 by Dick Oliver, R1 Box 5140, Morrisville, VT  05661
  8.    A program to "draw" and "paint" Sierpinksi's Triangle, defined by a
  9.    "seed" (or "parent") shape and three transformations of that shape
  10.    ("children"). The author makes no claims as to readability or
  11.    suitability for a particular task, but I'll be happy to give advice
  12.    and assistance. 
  13. *****************************************************************/
  14.  
  15. #include <stdio.h>   /* For getch() */
  16. #include <math.h>    /* For cos() and sin() */
  17. #include <graph.h>   /* For graphics calls */
  18.  
  19. #include "sierp.h"  /* You can change this for other template definitions */
  20.  
  21. int seedx[NPOINTS] = {SEEDX},   /* The "parent" polygon */
  22.     seedy[NPOINTS] = {SEEDY};
  23.  
  24.       /* The tranformations which define the "children" */
  25. float movex[NTRANS] = {MOVEX},  /* Displacement */
  26.       movey[NTRANS] = {MOVEY},
  27.       sizex[NTRANS] = {SIZEX},  /* Size change */
  28.       sizey[NTRANS] = {SIZEY},
  29.       spinx[NTRANS] = {SPINX},  /* Rotation */
  30.       spiny[NTRANS] = {SPINY},
  31.  
  32.       /* The transformation matrix T, computed from the above variables */
  33.       Ta[NTRANS], Tb[NTRANS], Tc[NTRANS], Td[NTRANS];
  34.  
  35. /* Function prototypes */
  36. void draw(float a, float b, float c, float d, float mx, float my, int iter);
  37. void paint(int mx, int my);
  38.  
  39. void main(void)
  40. {   int t;
  41.     _setvideomode(_VRES16COLOR);    /* Initialize the screen */
  42.     _clearscreen(_GCLEARSCREEN);
  43.  
  44.     /* Compute a,b,c,d from the move, size, and spin variables */
  45.     for (t = 0; t < NTRANS; t++)
  46.     {   Ta[t] =   sizex[t] * cos(spinx[t]);
  47.         Tb[t] = - sizey[t] * sin(spiny[t]);
  48.         Tc[t] =   sizex[t] * sin(spinx[t]);
  49.         Td[t] =   sizey[t] * cos(spiny[t]);
  50.     }
  51.     /* Invoke draw with an initial transformation to move the triangle
  52.        to the center of the screen, unchanged in size or rotation */
  53.     draw(1.0, 0.0, 0.0, 1.0, (float) CENTERX, (float) CENTERY, NLEVELS);
  54.     _settextposition(30,0);
  55.     _outtext("Press any key to paint.");
  56.     getch();
  57.     _clearscreen(_GCLEARSCREEN);
  58.  
  59.     /* Invoke paint, specifying the center of the screen */
  60.     paint(CENTERX, CENTERY);
  61.     _settextposition(30,0);
  62.     _outtext("Press any key to exit.");
  63.     getch();
  64.  
  65.     _setvideomode(_DEFAULTMODE); /* Go back to text mode and exit */
  66. }
  67.  
  68.  
  69. /* This recursive routine draws one "parent" polygon, then calls itself
  70.    to draw the "children" using the transformations defined above */
  71. void draw(float a, float b, float c, float d, float mx, float my, int iter)
  72. {   int t;
  73.     iter--;   /* Count one more level of drawing depth */
  74.     {     /* Use a,b,c,d,mx,my to transform the polygon */
  75.         float x1, y1;  /* Point on the parent */
  76.         int p, x2[NTRANS], y2[NTRANS]; /* Points on the child */
  77.         for (p = 0; p < NPOINTS; p++)
  78.         {   x1 = seedx[p];
  79.         y1 = seedy[p];
  80.         x2[p] = a * x1 + b * y1 + mx;
  81.         y2[p] = c * x1 + d * y1 + my;
  82.         }
  83.         /* Now draw the new polygon on the screen */
  84.         _moveto(x2[NPOINTS - 1], y2[NPOINTS - 1]);
  85.         for (p = 0; p < NPOINTS; p++) _lineto(x2[p], y2[p]);
  86.     }
  87.     if (iter < 0) return;  /* If we're at the deepest level, back out */
  88.  
  89.     /* Do a recursive call for each "child" of the polygon we just drew */
  90.     for (t = 0; t < NTRANS; t++)
  91.     {   draw(Ta[t] * a + Tc[t] * b,
  92.          Tb[t] * a + Td[t] * b,
  93.          Ta[t] * c + Tc[t] * d,
  94.          Tb[t] * c + Td[t] * d,
  95.          movex[t] * a + movey[t] * b + mx,
  96.          movex[t] * c + movey[t] * d + my,
  97.          iter);
  98.     }
  99. }
  100.  
  101.  
  102. /* This routine uses "random iteration" to paint the fractal dot-by-dot.
  103.    The resulting shape will be the same as if we called draw with a
  104.    huge value for the number of levels */
  105. void paint(int mx, int my)
  106. {   int t;
  107.     unsigned long ct = 0;    /* Counter for number of dots painted so far */
  108.     float x1 = 0.0, y1 = 0.0, x2, y2; /* Current and next dot */
  109.  
  110.     /* Keep going until a key is pressed or we reach the COUNT limit */
  111.     while(!kbhit() && (++ct < COUNT))
  112.     {   t = rand() % NTRANS;  /* Pick one of the transformations at random */
  113.  
  114.         /* Then move from a dot on the "whole" to the corresponding dot
  115.            on some transformed "part" */
  116.         x2 = x1 * Ta[t] + y1 * Tb[t] + movex[t];
  117.         y2 = x1 * Tc[t] + y1 * Td[t] + movey[t];
  118.         x1 = x2, y1 = y2;
  119.  
  120.         /* Skip the first few dots--it takes a while to "find" the fractal */
  121.         if (ct > 8) _setpixel((int) x2 + mx, (int) y2 + my);
  122.     }
  123. }
  124.  
  125.  
  126. [LISTING TWO]
  127.  
  128. /****************************************************************
  129.    SIERP.H --     Header file for Sierpinski's Triangle template
  130.      This (and the other header files like it) can be used to define
  131.      the initial fractal template for the SIERP.C and FRACDRAW.C programs
  132. *****************************************************************/
  133.  
  134. #define NPOINTS 3    /* Number of points on the "parent" polygon */
  135. #define NTRANS  3    /* Number of transformed "children" */
  136. #define NLEVELS 6    /* Number of levels to draw */
  137. #define COUNT 10000  /* Number of dots to paint */
  138. #define CENTERX 320  /* Center of the screen x, y*/
  139. #define CENTERY 240
  140. #define SEEDX -200,  200,  0  /* The "parent" polygon */
  141. #define SEEDY -200, -200, 200
  142.  
  143.         /* The tranformations which define the "children" */
  144. #define MOVEX -100.0,  100.0,   0.0  /* Displacement */
  145. #define MOVEY -100.0, -100.0, 100.0
  146. #define SIZEX   0.5,   0.5,   0.5    /* Size change */
  147. #define SIZEY   0.5,   0.5,   0.5
  148. #define SPINX   0.0,   0.0,   0.0    /* Rotation */
  149. #define SPINY   0.0,   0.0,   0.0
  150.  
  151. /* The following color definitions are ignored by the SIERP program
  152.    and used only by FRACDRAW.
  153.    PALETTE defines the 16-color VGA palette
  154.    COLOR intializes a two-dimensional array with color values:
  155.    each column in the array definition below corresponds to one level
  156.    of detail, and each row corresponds to a "part", or transformation.
  157.    Note that the array only needs to be 6 by 3 for the template defined
  158.    above, but more rows are included in case the user inserts additional
  159.    "parts".
  160. */
  161.  
  162. #define PALETTE {_BLACK, _RED, _GREEN, _CYAN, \
  163.          _BLUE, _MAGENTA, _BROWN, _WHITE, \
  164.          _GRAY, _LIGHTBLUE, _LIGHTGREEN, _LIGHTCYAN, \
  165.          _LIGHTRED, _LIGHTMAGENTA, _LIGHTYELLOW, _BRIGHTWHITE}
  166.  
  167. #define COLOR   {{2, 2, 2, 2, 2, 2},\
  168.              {1, 1, 1, 1, 1, 1},\
  169.          {5, 5, 5, 5, 5, 5},\
  170.          {4, 4, 4, 4, 4, 4},\
  171.          {2, 2, 2, 2, 2, 2},\
  172.          {3, 3, 3, 3, 3, 3},\
  173.          {7, 7, 7, 7, 7, 7},\
  174.          {8, 8, 8, 8, 8, 8},\
  175.          {1, 1, 1, 1, 1, 1}}
  176.          
  177.  
  178. [LISTING THREE]
  179.  
  180. /*****************************************************************
  181.    MAPLE.H --- Header file for maple tree template
  182.      This (and the other header files like it) can be used to define
  183.      the initial fractal template for the SIERP.C and FRACDRAW.C programs
  184. *****************************************************************/
  185. #define NPOINTS 4    /* Number of points on the "parent" polygon */
  186. #define NTRANS  3    /* Number of transformed "children" */
  187. #define NLEVELS 6    /* Number of levels to draw */
  188. #define COUNT 10000  /* Number of dots to paint */
  189. #define CENTERX 320  /* Center of the screen */
  190. #define CENTERY 350
  191.         /* The "parent" polygon */
  192. #define SEEDX 6,20,-6,-12  
  193. #define SEEDY -120,120,120,-120
  194.          /* The tranformations which define the "children" */
  195. #define MOVEX -6.1,-46,48  /* Displacement */
  196. #define MOVEY -156,-40,-38
  197. #define SIZEX  .65,.57,.58    /* Size change */
  198. #define SIZEY  .56,.77,.82
  199. #define SPINX   6.28,5.52,.44    /* Rotation */
  200. #define SPINY   6.28,5.52,.44
  201.  
  202. /* The following color definitions are ignored by the SIERP program
  203.    and used only by FRACDRAW.  See similar #defines in SIERP.H (Listing 2)
  204. */
  205. #define PALETTE {_BLACK, _RED, _GREEN, _CYAN, \
  206.          _BLUE, _MAGENTA, _BROWN, _WHITE, \
  207.          _GRAY, _LIGHTBLUE, _LIGHTGREEN, _LIGHTCYAN, \
  208.          _LIGHTRED, _LIGHTMAGENTA, _LIGHTYELLOW, _BRIGHTWHITE}
  209.  
  210. #define COLOR {{6, 6,14,14,10, 2},\
  211.                {6, 6,14,14,10, 2},\
  212.                {6, 6,14,14,10, 2},\
  213.                {6, 6,14,14,10, 2},\
  214.                {6, 6,14,14,10, 2},\
  215.                {6, 6,14,14,10, 2},\
  216.                {6, 6,14,14,10, 2},\
  217.                {6, 6,14,14,10, 2},\
  218.                {6, 6,14,14,10, 2}}
  219.  
  220. [LISTING FOUR]
  221.  
  222. /***************************************************************** 
  223.    FRACDRAW.C -- Drawing with fractals
  224.    Copyright 1990 by Dick Oliver, R1 Box 5140, Morrisville, VT  05661
  225.    A program for interactive fractal drawing.
  226.    The author makes no claims as to readability or suitability for a
  227.    particular task, but I'll be happy to give advice and assistance.
  228. *****************************************************************/
  229.  
  230. #include <stdio.h>
  231. #include <stdlib.h>
  232. #include <graph.h>
  233. #include <math.h>
  234. #include <ctype.h>
  235. #include <bios.h>
  236.  
  237.         /* #include file for initial template definition, can be changed */
  238. #include "maple.h"   
  239.         /* Numerical constants */
  240. #define PI 3.141592
  241. #define TWOPI 6.283853
  242. #define HALFPI 1.570796
  243. #define ALMOSTZERO 0.00002
  244. #define MAXSIZE 0.998
  245. #define MAXINT 32767
  246.         /* Keyboard constants */
  247. #define ENTER 13
  248. #define BACKSPACE 8
  249. #define ESC 27
  250. #define END -'O'
  251. #define HOME -'G'
  252. #define INSERT -'R'
  253. #define DELETE -'S'
  254. #define TAB 9
  255. #define UNTAB -15
  256. #define UP -'H'
  257. #define DN -'P'
  258. #define LT -'K'
  259. #define RT -'M'
  260. #define NULLKEY '^'
  261.  
  262.         /* Generic getch() replacement */
  263. #define geta if ((a = getch()) == 0) a = -getch();\
  264.            else if (a > 0) a = toupper(a)
  265.  
  266.         /* Main menu */
  267. #define MENUMSG "ACTION    KEY\n"\
  268.          "  Draw     D\n"\
  269.          "  Paint    P\n"\
  270.          "  Both     B\n"\
  271.          " Next Part Tab\n"\
  272.          " NextPoint ~\n"\
  273.          " Insert    Ins\n"\
  274.          " Delete    Del\n"\
  275.          "  Grow     *\n"\
  276.          "  Shrink   /\n"\
  277.          "  Spin     + -\n"\
  278.          "  Skew     ; \'\n"\
  279.          "  Squish   [\n"\
  280.          "  Stretch  ]\n"\
  281.          " Quit      ESC\n\n\n"\
  282.          "     DRAWING\n        WITH\n    FRACTALS\n\n"\
  283.          " (C) 1990 by\n Dick Oliver"
  284.  
  285. #define MENUKEYS {'D', 'P', 'B', TAB, '`', INSERT, DELETE, \
  286.            '*', '/', '+', ';', '[', ']', ESC}
  287. #define MENUWD 15 /* width of menu in characters */
  288. #define NMENUITEMS 14 /* number of menu items */
  289. #define HAND 64 /* size of handle in pixels */
  290. #define MAXPTS 19 /* max. no. of points on seed */
  291. #define MAXTRANS 19 /* max. no. of parts of template */
  292.  
  293. /* template variables:
  294.    spininc is the amount to rotate (in radians) each time spin is picked
  295.    sizeinc is the amount to grow or shrink
  296.    ra, rb, rc, rd, rmx, and rmy are the reverse of the initial tranformation
  297.    fa, fb, fc, and fd are the tranformations computed from
  298.    sizex, sizey, spinx, and spiny
  299.    movex and movey are the translation part of the transformations
  300.    asprat is the aspect ratio (always 1 for VGA)
  301.    fx and fy are used for various temporary storage purposes
  302.    x and y are the points on the seed polygon */
  303.  
  304. float sizeinc = 0.16, spininc = PI / 16,
  305.      ra, rb, rc, rd, rmx, rmy,
  306.      fa[MAXTRANS + 1], fb[MAXTRANS + 1], fc[MAXTRANS + 1], fd[MAXTRANS + 1],
  307.      sizex[MAXTRANS + 1] = {1, SIZEX}, sizey[MAXTRANS + 1] = {1, SIZEY},
  308.      spinx[MAXTRANS + 1] = {0, SPINX}, spiny[MAXTRANS + 1] = {0, SPINY},
  309.      movex[MAXTRANS + 1] = {CENTERX, MOVEX}, 
  310.      movey[MAXTRANS + 1] = {CENTERY, MOVEY},
  311.      asprat, fx, fy, x[MAXPTS] = {SEEDX}, y[MAXPTS] = {SEEDY};
  312.  
  313.      /* menu vars */
  314. char a, menukeys[] = MENUKEYS;
  315.  
  316. /* xtop, etc. are the points on the handle
  317.    drawclr is the text and handle color
  318.    xx, yy, midx, and midy are used for various pixel-shuffling operations
  319.    menuitem is the current menu choice
  320.    hand is the size of the handle in pixels
  321.    sk is used to keep track of when to re-sketch the template
  322.    xo and yo are the current template corners for quick erasing
  323.    thispt & thistran are the current point/part
  324.    npts is the number of point, ntrans is the number of parts,
  325.    level is the number of levels of detail to draw or paint
  326.    color determines the color to make each part at each level
  327. */
  328. int xtop, ytop, xctr, yctr, xlft, ylft, xrgt, yrgt,
  329.     drawclr, i, j, xx, yy, midx, midy, menuitem = 0, hand = HAND, sk,
  330.     xo[MAXTRANS + 1][MAXPTS], yo[MAXTRANS + 1][MAXPTS], moveinc = 16,
  331.     thispt = 0, thistran = 0, npts = NPOINTS, ntrans = NTRANS,
  332.     level = NLEVELS - 1, color[MAXTRANS][NLEVELS] = COLOR;
  333.  
  334.     /* ptmode means we're in "point" mode rather than "part" mode*/
  335. enum {OFF, ON} ptmode = OFF;
  336.  
  337.      /* standard Microsoft video variables */
  338. struct videoconfig vc;
  339. long palette[16] = PALETTE;
  340.  
  341.     /* these function prototypes are needed to avoid confusion about parameter
  342.      * types (most of the functions aren't prototyped) */
  343. void draw(float a, float b, float c, float d, float mx, float my, int iter);
  344. void warp(float spinxinc, float spinyinc, float sizexinc, float sizeyinc);
  345.  
  346. main()
  347. {   hello();        /* initialize everything */
  348.     while(1)        /* the main event-processing loop */
  349.     {      geta;       /* geta is a #define */
  350.         switch(a)   /* what shall we do now? */
  351.         {   case BACKSPACE:
  352.         case ' ':
  353.                     /* move ">" to new menu item */
  354.                 _settextposition(menuitem + 2, 1);
  355.                 _outtext(" ");
  356.                 if (a == ' ')
  357.                 {     if (++menuitem == NMENUITEMS) menuitem = 0;
  358.                 }
  359.                 else  if (--menuitem < 0) menuitem = NMENUITEMS - 1;
  360.                 _settextposition(menuitem + 2, 1);
  361.                 _outtext(">");
  362.                 break;
  363.             case ENTER:     /* pick a menu item */
  364.                 ungetch(menukeys[menuitem]);
  365.                 break;
  366.             default:
  367.         sk = 0;
  368.                 switch(a)
  369.                 {   case LT: case DN:
  370.                     case RT: case UP:
  371.                         /* move a point or part of the template */
  372.                         xx = 0, yy = 0;
  373.                         switch (a)
  374.                         {   case LT:      xx = -moveinc;   break;
  375.                             case RT:      xx = moveinc;    break;
  376.                             case UP:      yy = -moveinc;   break;
  377.                             case DN:      yy = moveinc;    break;
  378.                         }
  379.                         if (!ptmode && (thistran == 0))
  380.                             *movex += xx, *movey += yy;
  381.                         else
  382.                         {   if (ptmode)
  383.                             {   x[thispt] += xx * ra + yy * rb;
  384.                                 y[thispt] += xx * rc + yy * rd;
  385.                             }
  386.                             else movex[thistran] += xx * ra + yy * rb,
  387.                                  movey[thistran] += xx * rc + yy * rd;
  388.                         }
  389.                         break;
  390.                     case '/':          /* Shrink */
  391.                         if (ptmode)
  392.                         {    fx = 1 / (sizeinc + 1);
  393.                             warp(0.0, 0.0, fx, fx);
  394.                         }
  395.                         else
  396.                         {   if ((sizex[thistran] /= sizeinc + 1) == 0)
  397.                                 sizex[thistran] = ALMOSTZERO;
  398.                             if ((sizey[thistran] /= sizeinc + 1) == 0)
  399.                                 sizey[thistran] = ALMOSTZERO;
  400.                             computef(thistran);
  401.                         }
  402.                         break;
  403.                     case '*':            /* Grow */
  404.                          if (ptmode) warp(0.0, 0.0,sizeinc+1, sizeinc+1);
  405.                         else
  406.                         {   if (((sizex[thistran] *= sizeinc + 1)
  407.                                  > MAXSIZE)
  408.                                 && (thistran > 0))
  409.                                     sizex[thistran] = MAXSIZE;
  410.                             if (((sizey[thistran] *= sizeinc + 1)
  411.                                  > MAXSIZE)
  412.                                 && (thistran > 0))
  413.                                     sizey[thistran] = MAXSIZE;
  414.                             computef(thistran);
  415.                         }
  416.                         break;
  417.                     case '[':         /* Squish x-axis */
  418.                         if (ptmode) warp(0.0, 0.0, 1/(sizeinc + 1), 1.0);
  419.                         else
  420.                         {    if ((sizex[thistran] /= (sizeinc + 1)) == 0)
  421.                                 sizex[thistran] = ALMOSTZERO;
  422.                             computef(thistran);
  423.                         }
  424.                         break;
  425.                     case ']':    /* Stretch x-axis */
  426.                         if (ptmode) warp(0.0, 0.0, sizeinc + 1, 1.0);
  427.                         else
  428.                         {    if (((sizex[thistran] *= sizeinc + 1)
  429.                                  > MAXSIZE)
  430.                                 && (thistran > 0))
  431.                                     sizex[thistran] = MAXSIZE;
  432.                             computef(thistran);
  433.                         }
  434.                         break;
  435.                     case '-':      /* Spin counter-clockwise */
  436.                         if (ptmode) warp(-spininc, -spininc, 1.0, 1.0);
  437.                         else
  438.                         {   if ((spinx[thistran] -= spininc) < 0)
  439.                                 spinx[thistran] += TWOPI;
  440.                             if ((spiny[thistran] -= spininc) < 0)
  441.                                 spiny[thistran] += TWOPI;
  442.                             computef(thistran);
  443.                         }
  444.                         break;
  445.                     case '+':     /* Spin clockwise */
  446.                         if (ptmode) warp(spininc, spininc, 1.0, 1.0);
  447.                         else
  448.                         {   if ((spinx[thistran] += spininc) >= TWOPI)
  449.                                 spinx[thistran] -= TWOPI;
  450.                             if ((spiny[thistran] += spininc) >= TWOPI)
  451.                                 spiny[thistran] -= TWOPI;
  452.                             computef(thistran);
  453.                         }
  454.                         break;
  455.                     case ';':     /* Skew x-axis counter-clockwise */
  456.                         if (ptmode) warp(spininc, 0.0, 1.0, 1.0);
  457.                         else
  458.                         {   if ((spinx[thistran] += spininc) >= TWOPI)
  459.                                 spinx[thistran] -= TWOPI;
  460.                             computef(thistran);
  461.                         }
  462.                         break;
  463.                     case '\'':   /* Skew x-axis clockwise */
  464.                         if (ptmode) warp(-spininc, 0.0, 1.0, 1.0);
  465.                         else
  466.                         {   if ((spinx[thistran] -= spininc) < 0)
  467.                                 spinx[thistran] += TWOPI;
  468.                             computef(thistran);
  469.                         }
  470.                         break;
  471.                     case '`':    /* NextPoint */
  472.                         if (ptmode) ++thispt;
  473.                         else ptmode = ON, thistran = 0;
  474.                         if (thispt >= npts) thispt = 0;
  475.                         break;
  476.                     default:
  477.                         switch(a)
  478.                         {   case TAB: /* Next part */
  479.                                 if (ptmode)
  480.                                 {    ptmode = OFF;
  481.                                      midpoint();
  482.                                 }
  483.                                 else
  484.                                 {    if (++thistran > ntrans) thistran = 0;
  485.                                 }
  486.                                 break;
  487.                             case 'D':
  488.                             case 'P':
  489.                             case 'B':   /* Draw and/or Paint */
  490.                                 _clearscreen(_GCLEARSCREEN);
  491.                                 _setcliprgn(0, 0,
  492.                                            vc.numxpixels - 1,
  493.                                            vc.numypixels - 1);
  494.                                 _setcolor(**color);
  495.                                 if ((a == 'D') || (a == 'B'))
  496.                                     draw(*fa, *fb, *fc, *fd, 
  497.                          *movex, *movey, level);
  498.                                 if ((a == 'P') || (a == 'B')) paint();
  499.                                 printf("\7");
  500.                                 getch();
  501.                                 _clearscreen(_GCLEARSCREEN);
  502.                                 printmenu();
  503.                                 break;
  504.                             case ESC:   /* Quit */
  505.                                 _setvideomode(_DEFAULTMODE);
  506.                                 printf("Seeyalater!");
  507.                                 exit(0);
  508.                             case INSERT:  /* Insert a point or part */
  509.                                 if (ptmode)
  510.                                 {   if (npts < MAXPTS)
  511.                                     {   erase();
  512.                                         ++npts;
  513.                                         for (i = npts - 1; i > thispt; i--)
  514.                                             x[i] = x[i - 1],
  515.                                             y[i] = y[i - 1];
  516.                                         if (thispt > 0)
  517.                                             xx = x[thispt - 1],
  518.                                             yy = y[thispt - 1];
  519.                                         else xx = x[npts - 1],
  520.                                             yy = y[npts - 1];
  521.                                         if ((xx == x[thispt]) &&
  522.                                             (yy == y[thispt]))
  523.                                             x[thispt] += moveinc,
  524.                                             y[thispt] += moveinc;
  525.                                         else x[thispt] =
  526.                                                 (xx + x[thispt]) / 2,
  527.                                             y[thispt] =
  528.                                                 (yy + y[thispt]) / 2;
  529.                                     }
  530.                                     else printf("\7");
  531.                                 }
  532.                                 else
  533.                                 {   if ((ntrans < MAXTRANS) && (ntrans > 0))
  534.                                     {   ++ntrans;
  535.                                         for (i = ntrans; i > thistran; i--)
  536.                                         {   if (i > 1)
  537.                                             {   movex[i] = movex[i - 1];
  538.                                                 movey[i] = movey[i - 1];
  539.                                                 spinx[i] = spinx[i - 1];
  540.                                                 spiny[i] = spiny[i - 1];
  541.                                                 sizex[i] = sizex[i - 1];
  542.                                                 sizey[i] = sizey[i - 1];
  543.                                                 for (j = 0; j < NLEVELS;
  544.                                                     j++)
  545.                                                     color[i - 1][j] =
  546.                                                         color[i - 2][j];
  547.                                                 fa[i] = fa[i - 1];
  548.                                                 fb[i] = fb[i - 1];
  549.                                                 fc[i] = fc[i - 1];
  550.                                                 fd[i] = fd[i - 1];
  551.                                             }
  552.                                             else
  553.                                             {   spinx[1] = 0;
  554.                                                 spiny[1] = 0;
  555.                                                 sizex[1] = sizey[1];
  556.                                                 computef(1);
  557.                                             }
  558.                                         }
  559.                                         if (thistran == 0) thistran = 1,i = 1;
  560.                                         if (thistran > 1) j = thistran - 1;
  561.                                         else j = ntrans;
  562.                                         if ((movex[i] == movex[j]) &&
  563.                                             (movey[i] == movey[j]))
  564.                                             movex[i] += moveinc,
  565.                                             movey[i] += moveinc;
  566.                                         else movex[i] =
  567.                                                 (movex[i] + movex[j]) / 2,
  568.                                             movey[i] =
  569.                                                 (movey[i] + movey[j]) / 2;
  570.                                     }
  571.                                     else
  572.                                     {   if (ntrans == 0) thistran = ++ntrans;
  573.                                         else printf("\7");
  574.                                     }
  575.                                 }
  576.                                 break;
  577.                             case DELETE:   /* Delete a point or part */
  578.                                 erase();
  579.                                 if (ptmode)
  580.                                 {   if (npts > 1)
  581.                                     {   if (thispt == --npts) --thispt;
  582.                                         else for (i = thispt; i < npts; i++)
  583.                                                 x[i] = x[i + 1],
  584.                                                 y[i] = y[i + 1];
  585.                                     }
  586.                                     else printf("\7");
  587.                                 }
  588.                                 else
  589.                                 {   if (ntrans > 0)
  590.                                     {   --ntrans;
  591.                                     }
  592.                                     else printf("\7");
  593.                                     if (ntrans > 0)
  594.                                     {   if (thistran == 0) thistran = 1;
  595.                                         else
  596.                                             for (i = thistran;
  597.                                                 i <= ntrans; i++)
  598.                                             {   movex[i] = movex[i + 1];
  599.                                                 movey[i] = movey[i + 1];
  600.                                                 spinx[i] = spinx[i + 1];
  601.                                                 spiny[i] = spiny[i + 1];
  602.                                                 sizex[i] = sizex[i + 1];
  603.                                                 sizey[i] = sizey[i + 1];
  604.                                                 for (j = 0; j < NLEVELS;
  605.                                                     j++)
  606.                                                     color[i - 1][j] =
  607.                                                         color[i][j];
  608.                                                 fa[i] = fa[i + 1];
  609.                                                 fb[i] = fb[i + 1];
  610.                                                 fc[i] = fc[i + 1];
  611.                                                 fd[i] = fd[i + 1];
  612.                                             }
  613.                                     }
  614.                                     if (thistran > ntrans) --thistran;
  615.                                 }
  616.                         }
  617.                         sk = 1;
  618.                 }
  619.                 erase();
  620.                 sketch(sk);
  621.         }
  622.     }
  623. }
  624.     /* midpoint() -- find the center of the seed */
  625. midpoint()      
  626. {   int xx, yy;
  627.     midx = 0, midy = 0;
  628.     for (i = 0; i < npts; i++) midx += x[i], midy += y[i];
  629.     midx /= npts, midy /= npts;
  630.     for (i = 0; i < npts; i++) x[i] -= midx, y[i] -= midy;
  631.     for (i = 1; i <= ntrans; i++)
  632.     {   xx = midx * fa[i] + midy * fb[i];
  633.         yy = midx * fc[i] + midy * fd[i];
  634.         movex[i] -= midx - xx;
  635.         movey[i] -= midy - yy;
  636.     }
  637.     xx = midx * *fa + midy * *fb,
  638.     yy = midx * *fc + midy * *fd;
  639.     *movex += xx,
  640.     *movey += yy;
  641. }
  642.  
  643.     /* compute the affine transformations expressed by the template */
  644. computef(int i)
  645. {   fa[i] =  sizex[i] * cos(spinx[i]);
  646.     fb[i] = -sizey[i] * sin(spiny[i]);
  647.     fc[i] =  sizex[i] * sin(spinx[i]);
  648.     fd[i] =  sizey[i] * cos(spiny[i]);
  649.     if (i == 0)
  650.     {   if ((fx = *fa * *fd - *fb * *fc) == 0) fx = 0.001;
  651.         ra = *fd / fx;
  652.         rb = - *fb / fx;
  653.         rc = - *fc / fx;
  654.         rd = *fa / fx;
  655.     }
  656. }
  657.      /* warp the seed shape  (used to skew, squish, and stretch) */
  658. void warp(float spinxinc, float spinyinc, float sizexinc, float sizeyinc)
  659. {   float a, b, c, d, dsizex, dsizey, dspinx, dspiny;
  660.     dspinx = spinxinc + *spinx;
  661.     dspiny = spinyinc + *spiny;
  662.     dsizex = sizexinc * *sizex;
  663.     dsizey = sizeyinc * *sizey;
  664.     a =  cos(dspinx) * dsizex;
  665.     b = -sin(dspiny) * dsizey;
  666.     c =  sin(dspinx) * dsizex;
  667.     d =  cos(dspiny) * dsizey;
  668.     for (i = 0; i < MAXPTS; i++)
  669.     {   fx = x[i] * a + y[i] * b;
  670.         fy = x[i] * c + y[i] * d;
  671.         x[i] = fx * ra + fy * rb;
  672.         y[i] = fx * rc + fy * rd;
  673.     }
  674. }
  675.  
  676.     /*  sketch() -- sketch the template and the handle.
  677.      *  Note that the handle shows not only which part you are on,
  678.      *  but also the relative size and orientation of both axes. */
  679. sketch(int all)
  680. {   int i, j, x1, y1, inc, tran0 = 0;
  681.     float x2, y2, a, b, c, d, mx, my;
  682.     inc = hand;
  683.     if (ptmode)
  684.     {   tran0 = 1;
  685.         inc *= *sizey / 2;
  686.         fx = x[thispt],  fy = y[thispt];
  687.         x1 = fx * *fa + fy * *fb + *movex;
  688.         y1 = fx * *fc + fy * *fd + *movey;
  689.         xctr = x1, yctr = (y1 + inc) * asprat;
  690.         xtop = x1, ytop = (y1 - inc) * asprat;
  691.         y1 *= asprat;
  692.         xlft = x1 - inc, ylft = y1;
  693.         xrgt = x1 + inc, yrgt = y1;
  694.     }
  695.     else
  696.     {   if (thistran == 0) x1 = 0, y1 = 0, tran0 = 1;
  697.         else x1 = movex[thistran], y1 = movey[thistran];
  698.         if (tran0) fx = x1, fy = y1 - inc;
  699.         else fx = x1 - inc * fb[thistran],
  700.             fy = y1 - inc * fd[thistran];
  701.         xtop = fx * *fa + fy * *fb + *movex;
  702.         ytop = (fx * *fc + fy * *fd + *movey) * asprat;
  703.         xctr = x1 * *fa + y1 * *fb + *movex;
  704.         yctr = (x1 * *fc + y1 * *fd + *movey) * asprat;
  705.         inc /= 2;
  706.         if (tran0) fx = x1 - inc, fy = y1;
  707.         else fx = x1 - inc * fa[thistran],
  708.             fy = y1 - inc * fc[thistran];
  709.         xlft = fx * *fa + fy * *fb + *movex;
  710.         ylft = (fx * *fc + fy * *fd + *movey) * asprat;
  711.         if (tran0) fx = x1 + inc, fy = y1;
  712.         else fx = x1 + inc * fa[thistran],
  713.             fy = y1 + inc * fc[thistran];
  714.         xrgt = fx * *fa + fy * *fb + *movex;
  715.         yrgt = (fx * *fc + fy * *fd + *movey) * asprat;
  716.     }
  717.     _setcolor(**color);
  718.     for (j = 0; j < npts; j++)
  719.     {   x1 = x[j] * *fa + y[j] * *fb + *movex;
  720.         y1 = (x[j] * *fc + y[j] * *fd + *movey) * asprat;
  721.         (*xo)[j] = x1, (*yo)[j] = y1;
  722.         if (j == 0) _moveto(x1, y1);
  723.         else _lineto(x1, y1);
  724.     }
  725.     _lineto(**xo, **yo);
  726.     for (i = 1; i <= ntrans; i++)
  727.     {   if ((thistran == 0) || (i == thistran) || (all))
  728.         {   _setcolor(color[i - 1][level]);
  729.             a = fa[i] * *fa + fc[i] * *fb;
  730.             b = fb[i] * *fa + fd[i] * *fb;
  731.             c = fa[i] * *fc + fc[i] * *fd;
  732.             d = fb[i] * *fc + fd[i] * *fd;
  733.             mx = movex[i] * *fa + movey[i] * *fb + *movex;
  734.             my = movex[i] * *fc + movey[i] * *fd + *movey;
  735.             for (j = 0; j < npts; j++)
  736.             {   x1 = a * x[j] + b * y[j] + mx;
  737.                 y1 = (c * x[j] + d * y[j] + my) * asprat;
  738.                 if (j == 0) _moveto(x1, y1);
  739.                 else _lineto(x1, y1);
  740.                 xo[i][j] = x1, yo[i][j] = y1;
  741.             }
  742.             _lineto(*(xo[i]), *(yo[i]));
  743.         }
  744.     }
  745.     _setcolor(drawclr);
  746.     _moveto(xtop, ytop);
  747.     _lineto(xctr, yctr);
  748.     _moveto(xlft, ylft);
  749.     _lineto(xrgt, yrgt);
  750. }
  751.     /* erase the template */
  752. erase()
  753. {   _setcolor(0);
  754.     _moveto(**xo, **yo);
  755.     for (i = 1; i < npts; i++) _lineto((*xo)[i], (*yo)[i]);
  756.     _lineto(**xo, **yo);
  757.     for (i = 1; i <= ntrans; i++)
  758.     {   if ((thistran == 0) || (i == thistran))
  759.         {   _moveto(*(xo[i]), *(yo[i]));
  760.             for (j = 0; j < npts; j++) _lineto(xo[i][j], yo[i][j]);
  761.             _lineto(*(xo[i]), *(yo[i]));
  762.         }
  763.     }
  764.     _moveto(xtop, ytop);
  765.     _lineto(xctr, yctr);
  766.     _moveto(xlft, ylft);
  767.     _lineto(xrgt, yrgt);
  768. }
  769.  
  770.    /* paint() -- uses the "Chaos Game", or "random iteration" algorithm
  771.     *            to paint the "infinite-level" fractal on the screen. */
  772. paint()
  773. {   int i, j, p[MAXTRANS], tc, tp, ci[NLEVELS], cc = 0, mx, my;
  774.     unsigned long ct = COUNT;
  775.     float x1 = 0.0, y1 = 0.0, x2, y2 = 0, sx[MAXTRANS], sy[MAXTRANS];
  776.     mx = *movex, my = *movey;
  777.  
  778.     /* First, we need to compute the relative area of each part of the
  779.        template.  This is done by comparing the size of the determinants
  780.        of the matrix (a,b,c,d).  These weights are then used to decide
  781.        how often to visit each part--big parts get more visits than small
  782.        ones, giving the overall fractal an even density. */
  783.     for (i = 1; i <= ntrans; i++)
  784.         y2 += (sx[i - 1] =
  785.                 fabs(fa[i] * fd[i] - fb[i] * fc[i]));
  786.     if (y2 == 0) y2 = 0.01;
  787.     x2 = MAXINT / y2;
  788.     j = 0;
  789.     for (i = 0; i < ntrans; i++)
  790.     {   if ((xx = sx[i] * x2) == 0) xx = 1;
  791.         p[i] = (j += xx);
  792.     }
  793.  
  794.     /* We skip the first eight points on our journey, because it may take
  795.        that long to settle down from wherever we started onto the fractal.*/
  796.     for (j = 0; j < 8; j++)
  797.     {   i = rand() % ntrans + 1;
  798.         x2 = x1 * fa[i] + y1 * fb[i] + movex[i];
  799.         y2 = x1 * fc[i] + y1 * fd[i] + movey[i];
  800.         x1 = x2, y1 = y2;
  801.         ci[cc] = i;
  802.         if (++cc == level) cc = 0;
  803.     }
  804.  
  805.     /* Now we put it on the screen.  The cc, tc, and ci variables are used
  806.        to determine coloring.  At each iteration, we choose a level at
  807.        random out of all the levels we will be coloring.  We then find the
  808.        color for that level based on which part was "visited" that many
  809.        iterations ago.  How does this work?  Each iteration of the orbit
  810.        goes from a point on the "whole" to a point on a "part".  Therefore,
  811.        if we were in part #3 one iteration ago, we are now in a level 1
  812.        reflection of part #3 within the current part.  If we were at part #5
  813.        two cycles ago, we are now painting a point within a level 2
  814.        reflection of part #5, and so on.  */
  815.     while(!kbhit() && (--ct != 0))
  816.     {   j = rand();
  817.         for (i = 0; i < ntrans; i++) if (j < p[i]) break;
  818.         i++;
  819.         x2 = x1 * fa[i] + y1 * fb[i] + movex[i];
  820.         y2 = x1 * fc[i] + y1 * fd[i] + movey[i];
  821.         x1 = x2, y1 = y2;
  822.         ci[cc] = i - 1;
  823.         j = rand() % level;
  824.         if ((i = cc - j) < 0) i += level;
  825.         if ((tc = color[ci[i]][j + 1]) > 0)
  826.         {   _setcolor(tc);
  827.             _setpixel((int) (x2 * *fa + y2 * *fb + mx),
  828.                     (int) ((x2 * *fc + y2 * *fd + my) * asprat));
  829.         }
  830.         if (++cc == level) cc = 0;
  831.     }
  832. }
  833.  
  834. /* draw() -- uses the "successive approximation" algorithm to draw
  835.    the fractal.*/
  836. void draw(float a, float b, float c, float d, float mx, float my, int iter)
  837. {   int i;
  838.  
  839.     /* When we start drawing, iter is the number of levels to draw.
  840.        Each time we go down one level, we decrement iter. */
  841.     iter--;
  842.  
  843.     /* If user hits ESC, pass that keypress up through the recursive
  844.        calls until we get back to the main procedure.*/
  845.     if (kbhit() && (getch() == ESC))
  846.     {   ungetch(ESC);
  847.         return;
  848.     }
  849.  
  850.     /*  Draw a reflection of the seed polygon using the current
  851.         transformation */
  852.     for (i = 0; i < npts; i++)
  853.     {    fx = x[i] * a + y[i] * b + mx;
  854.          fy = x[i] * c + y[i] * d + my;
  855.          if (i == 0)
  856.          {    xx = fx, yy = fy;
  857.               _moveto((int) fx, (int) (fy * asprat));
  858.          }
  859.          else _lineto((int) fx, (int) (fy * asprat));
  860.     }
  861.     _lineto((int) xx, (int) (yy * asprat));
  862.  
  863.     /* If iter has counted all the way down to zero, don't draw the next
  864.        deepest level, but back out one level instead */
  865.  
  866.     if (iter < 0) return;
  867.     else
  868.     {   /* Call draw recursively for each transformation, drawing the
  869.            next deepest level of each part */
  870.         for (i = 1; i <= ntrans; i++)
  871.         {   _setcolor(color[i - 1][level - iter]);
  872.             draw(fa[i] * a + fc[i] * b,
  873.                  fb[i] * a + fd[i] * b,
  874.                  fa[i] * c + fc[i] * d,
  875.                  fb[i] * c + fd[i] * d,
  876.                  a * movex[i] + b * movey[i] + mx,
  877.                  c * movex[i] + d * movey[i] + my,
  878.                  iter);
  879.         }
  880.     }
  881. }
  882.  
  883.     /* display the menu */
  884. printmenu()
  885. {   _settextwindow(1, vc.numtextcols - MENUWD,
  886.               vc.numtextrows, vc.numtextcols);
  887.     _clearscreen(_GWINDOW);
  888.     _outtext(MENUMSG);
  889.     _settextposition(menuitem + 2, 1);
  890.     _outtext(">");
  891.     _setcliprgn(0, 0, vc.numxpixels - (MENUWD + 1) *
  892.                 (vc.numxpixels / vc.numtextcols) - 1,
  893.                 vc.numypixels - 1);
  894. }
  895.  
  896.     /* hello() -- initialize everything */
  897. hello()
  898. {   if (!_setvideomode(_VRES16COLOR))
  899.     {   printf("Can't set video mode.  VGA required.");
  900.     }
  901.     _getvideoconfig(&vc);
  902.     _remapallpalette(palette);
  903.     _wrapon(_GWRAPOFF);
  904.     _clearscreen(_GCLEARSCREEN);
  905.     printmenu();
  906.     asprat = (float) (4 * vc.numypixels) / (float) (3 * vc.numxpixels);
  907.     drawclr = vc.numcolors - 1;
  908.     for (i = 0; i <= ntrans; i++) computef(i);
  909.     sketch(0);
  910. }
  911.  
  912. [LISTING FIVE]
  913.  
  914. /*****************************************************************
  915.      FLAKE.H --- Header file for snowflake template
  916.      This (and the other header files like it) can be used to define
  917.      the initial fractal template for the SIERP.C and FRACDRAW.C programs
  918.      This template models the crystalization process to draw a realistic
  919.      snowflake shape.  
  920.      See additional comments in SIERP.H
  921. *****************************************************************/
  922. #define NPOINTS 6    /* Number of points on the "parent" polygon */
  923. #define NTRANS  6    /* Number of transformed "children" */
  924. #define NLEVELS 5    /* Number of levels to draw */
  925. #define COUNT 10000  /* Number of dots to paint */
  926. #define CENTERX 320  /* Center of the screen */
  927. #define CENTERY 240
  928. #define SEEDX 1,21,21,1,-21,-21  /* The "parent" polygon */
  929. #define SEEDY -27,-15,9,40,9,-15
  930.  
  931. /* The tranformations which define the "children" */
  932. #define MOVEX -1,55,55,1,-55,-55  /* Displacement */
  933. #define MOVEY -65,-35,35,65,35,-35
  934. #define SIZEX   .18,.18,.18,.18,.18,.18    /* Size change */
  935. #define SIZEY   .91,.91,.91,.91,.91,.91
  936. #define SPINX   0,1.05,2.09,3.14,4.19,5.24    /* Rotation */
  937. #define SPINY   0,1.05,2.09,3.14,4.19,5.24
  938.  
  939. #define PALETTE {_BLACK, _RED, _GREEN, _CYAN, \
  940.              _BLUE, _MAGENTA, _BROWN, _WHITE, \
  941.          _GRAY, _LIGHTBLUE, _LIGHTGREEN, _LIGHTCYAN, \
  942.          _LIGHTRED, _LIGHTMAGENTA, _LIGHTYELLOW, _BRIGHTWHITE}
  943.  
  944. #define COLOR {{15,15,15,15,15},\
  945.                {15,15,15,15,15},\
  946.                {15,15,15,15,15},\
  947.                {15,15,15,15,15},\
  948.                {15,15,15,15,15},\
  949.                {15,15,15,15,15},\
  950.                {15,15,15,15,15},\
  951.                {15,15,15,15,15},\
  952.                {15,15,15,15,15}}
  953.  
  954. [LISTING SIX]
  955.  
  956. /****************************************************************
  957.    CUMULUS.H--- Header file for cumulus cloud template 
  958.    This (and the other header files like it) can be used to define
  959.    the initial fractal template for the SIERP.C and FRACDRAW.C programs
  960.    See additional comments in SIERP.H
  961. ****************************************************************/
  962.  
  963. #define NPOINTS 7    /* Number of points on the "parent" polygon */
  964. #define NTRANS  6    /* Number of transformed "children" */
  965. #define NLEVELS 5    /* Number of levels to draw */
  966. #define COUNT 10000  /* Number of dots to paint */
  967. #define CENTERX 320  /* Center of the screen */
  968. #define CENTERY 240
  969. #define SEEDX 23,17,-4,-10,-27,7,44  /* The "parent" polygon */
  970. #define SEEDY 0,55,55,0,9,-66,10
  971.  
  972. /* The tranformations which define the "children" */
  973. #define MOVEX   85,-94,-3,51.5,-49,0  /* Displacement */
  974. #define MOVEY   15,13,3.5,-35,-40,40
  975. #define SIZEX   .36,.4,.53,.48,.4,.87    /* Size change */
  976. #define SIZEY   .36,.47,.53,.53,.4,.33
  977. #define SPINX   .25,6,6.2,0.15,6.2,0    /* Rotation */
  978. #define SPINY   .25,6,6.2,0.15,6.2,6.3
  979.  
  980. #define PALETTE {_BLACK, _RED, _GREEN, _CYAN, \
  981.         _BLUE, _MAGENTA, _BROWN, _WHITE, \
  982.         _GRAY, _LIGHTBLUE, _LIGHTGREEN, _LIGHTCYAN, \
  983.         _LIGHTRED, _LIGHTMAGENTA, _LIGHTYELLOW, _BRIGHTWHITE}
  984.  
  985. #define COLOR {{15,15,15, 7, 8},\
  986.                {15,15,15,15,15},\
  987.                {15,15,15,15,15},\
  988.                {15,15,15,15,15},\
  989.                {15,15,15,15,15},\
  990.                {15,15,15,15,15},\
  991.                {15,15,15,15,15},\
  992.                {15,15,15,15,15},\
  993.                {15,15,15,15,15}}
  994.  
  995. /*****************************************************************
  996.    CIRRUS.H--    Header file for cirrus cloud template
  997.      In this and the other cloud models (STRATUS and CUMULUS), the air
  998.      currents which control cloud formation are modelled as arrows.
  999.      When those forces are reflected throughout all levels of scale,
  1000.      a realistic image of the cloud type that results from those air
  1001.      currents appears.  Cirrus clouds are characterized by high-altitude
  1002.      rising cross winds, stratus clouds by slow horizontal air flow,
  1003.      and cumulus clouds by warm air rising from the ground.
  1004. *****************************************************************/
  1005.  
  1006. #define NPOINTS 7    /* Number of points on the "parent" polygon */
  1007. #define NTRANS  6    /* Number of transformed "children" */
  1008. #define NLEVELS 5    /* Number of levels to draw */
  1009. #define COUNT 10000  /* Number of dots to paint */
  1010. #define CENTERX 180  /* Center of the screen */
  1011. #define CENTERY 240
  1012. #define SEEDX 16,-27,-42,-7,-27,54,23  /* The "parent" polygon */
  1013. #define SEEDY  33,52,36,-7,-13,-43,36
  1014.  
  1015. /* The tranformations which define the "children" */
  1016. #define MOVEX 143.4,-90,5,-4  /* Displacement */
  1017. #define MOVEY 11.08,13.6,-15.5,45
  1018. #define SIZEX   .75,.43,.38,.75    /* Size change */
  1019. #define SIZEY   .45,.47,.44,.21
  1020. #define SPINX   6.07,0.05,0.02,0.0    /* Rotation */
  1021. #define SPINY   6.07,0.05,0.02,6.28
  1022.  
  1023. #define PALETTE {_BLACK, _RED, _GREEN, _CYAN, \
  1024.          _BLUE, _MAGENTA, _BROWN, _WHITE, \
  1025.          _GRAY, _LIGHTBLUE, _LIGHTGREEN, _LIGHTCYAN, \
  1026.          _LIGHTRED, _LIGHTMAGENTA, _LIGHTYELLOW, _BRIGHTWHITE}
  1027.  
  1028. #define COLOR {{15,15,15, 7, 8},\
  1029.                {15,15,15,15,15},\
  1030.                {15,15,15,15,15},\
  1031.                {15,15,15,15,15},\
  1032.                {15,15,15,15,15},\
  1033.                {15,15,15,15,15},\
  1034.                {15,15,15,15,15},\
  1035.                {15,15,15,15,15},\
  1036.                {15,15,15,15,15}}
  1037.  
  1038.  
  1039. /*****************************************************************
  1040.    LEAF.H ---     Header file for maple leaf template
  1041.     This is the "geometric genetic code" for a maple leaf.  Note the close
  1042.     similarity to the MAPLE tree template.
  1043. *****************************************************************/
  1044. #define NPOINTS 4    /* Number of points on the "parent" polygon */
  1045. #define NTRANS  4    /* Number of transformed "children" */
  1046. #define NLEVELS 6    /* Number of levels to draw */
  1047. #define COUNT 10000  /* Number of dots to paint */
  1048. #define CENTERX 320  /* Center of the screen */
  1049. #define CENTERY 350
  1050. #define SEEDX 6,20,-6,-12  /* The "parent" polygon */
  1051. #define SEEDY -120,120,120,-120
  1052.  
  1053. /* The tranformations which define the "children" */
  1054. #define MOVEX -1.15,-53,51,-6  /* Displacement */
  1055. #define MOVEY 35,7,6,-111
  1056. #define SIZEX  0.14,0.62,0.65,0.49 /* Size change */
  1057. #define SIZEY  0.51,0.72,0.68,0.51
  1058. #define SPINX  6.26,5.47,0.81,6.28 /* Rotation */
  1059. #define SPINY  6.26,5.47,0.81,6.28
  1060.  
  1061. #define PALETTE {_BLACK, _RED, _GREEN, _CYAN, \
  1062.          _BLUE, _MAGENTA, _BROWN, _WHITE, \
  1063.          _GRAY, _LIGHTBLUE, _LIGHTGREEN, _LIGHTCYAN, \
  1064.          _LIGHTRED, _LIGHTMAGENTA, _LIGHTYELLOW, _BRIGHTWHITE}
  1065.  
  1066. #define COLOR {{6, 6,14,14,10, 2},\
  1067.                {6, 6,14,14,10, 2},\
  1068.                {6, 6,14,14,10, 2},\
  1069.                {6, 6,14,14,10, 2},\
  1070.                {6, 6,14,14,10, 2},\
  1071.                {6, 6,14,14,10, 2},\
  1072.                {6, 6,14,14,10, 2},\
  1073.                {6, 6,14,14,10, 2},\
  1074.                {6, 6,14,14,10, 2}}
  1075.  
  1076. /*****************************************************************
  1077.    MOUSE.H  --     Header file for cartoon mouse template
  1078.      This template was made by tracing the rough outline of an image and
  1079.      tiling with copies of itself.
  1080. *****************************************************************/
  1081. #define NPOINTS 14    /* Number of points on the "parent" polygon */
  1082. #define NTRANS  18    /* Number of transformed "children" */
  1083. #define NLEVELS 2    /* Number of levels to draw */
  1084. #define COUNT 50000  /* Number of dots to paint */
  1085. #define CENTERX 320  /* Center of the screen */
  1086. #define CENTERY 240
  1087. #define SEEDX 131,140,97,6,-56,-97,-146,-148,-121,-101,-47,-3,32,29
  1088. #define SEEDY 5,55,99,133,121,70,21,-17,-17,-31,-20,-78,-93,-71
  1089.  
  1090. /* The tranformations which define the "children" */
  1091. #define MOVEX -89,36,-60,-4,4,61,-71,1,81,-49,-133,-130,-8,-3,-36,-24,13,15
  1092. #define MOVEY -3,13,25,-35,-63,-43,101,116,56,87,-50,-24,104,-1,-20,-27,-16,76
  1093. #define SIZEX .31,.4,.62,.07,.19,.32,.19,.4,.55,.31,.12,.17,.21,.06,.06,\
  1094.           .08,.11,.42
  1095. #define SIZEY .18,.35,.44,.27,.27,.48,.06,.13,.33,.20,.04,.23,.12,.16,.14,\
  1096.           .2,.23,.2
  1097. #define SPINX 3.23,6.4,.32,2.72,5.84,4.61,.75,6.25,5.34,.29,3.16,5.9,3.04,\
  1098.               4.15,4.32,.91,1.1,2.55
  1099. #define SPINY 3.6,6.5,.77,.37,3.49,4.28,.75,6.25,5.27,.1,2.85,2.65,2.53,\
  1100.               3.56,3.73,3.73,3.53,5.89
  1101.  
  1102. #define PALETTE {_BLACK, _RED, _GREEN, _CYAN, \
  1103.          _BLUE, _MAGENTA, _BROWN, _WHITE, \
  1104.          _GRAY, _LIGHTBLUE, _LIGHTGREEN, _LIGHTCYAN, \
  1105.          _LIGHTRED, _LIGHTMAGENTA, _LIGHTYELLOW, _BRIGHTWHITE}
  1106.  
  1107. #define COLOR {{6,6},\
  1108.                {6,6},\
  1109.                {6,6},\
  1110.                {6,6},\
  1111.                {6,6},\
  1112.                {6,6},\
  1113.                {1,1},\
  1114.                {6,6}, {6,6}, {1,1}, {7,7}, {8,8}, {12,12},\
  1115.                {9,9}, {9,9}, {15,15}, {15,15}, {1,1}}
  1116.  
  1117. /*****************************************************************
  1118.    PINE.H --- Header file for pine tree template
  1119.      This (and the other header files like it) can be used to define
  1120.      the initial fractal template for the SIERP.C and FRACDRAW.C programs
  1121. *****************************************************************/
  1122.  
  1123. #define NPOINTS 4    /* Number of points on the "parent" polygon */
  1124. #define NTRANS  6    /* Number of transformed "children" */
  1125. #define NLEVELS 5    /* Number of levels to draw */
  1126. #define COUNT 10000  /* Number of dots to paint */
  1127. #define CENTERX 320  /* Center of the screen */
  1128. #define CENTERY 350
  1129. #define SEEDX 6,20,-6,-12  /* The "parent" polygon */
  1130. #define SEEDY -120,120,120,-120
  1131.  
  1132. /* The tranformations which define the "children" */
  1133.  
  1134. #define MOVEX -41.2,36.9,5.13,-14.64,2.2,40.07 /* Displacement */
  1135. #define MOVEY 14.987,-61.31,7.10,-32.33,-50.46
  1136. #define SIZEX  0.39,0.41,0.52,0.35,0.86,0.37 /* Size change */
  1137. #define SIZEY  0.39,0.31,0.17,0.24,0.79,0.42
  1138. #define SPINX  5.62,0.61,6.15,5.43,3.27,0.54 /* Rotation */
  1139. #define SPINY  4.91,1.27,0.13,4.71,6.28,1.4
  1140.  
  1141. #define PALETTE {_BLACK, _RED, _GREEN, _CYAN, \
  1142.         _BLUE, _MAGENTA, _BROWN, _WHITE, \
  1143.         _GRAY, _LIGHTBLUE, _LIGHTGREEN, _LIGHTCYAN, \
  1144.         _LIGHTRED, _LIGHTMAGENTA, _LIGHTYELLOW, _BRIGHTWHITE}
  1145.  
  1146. #define COLOR {{6, 6,14,10, 2},\
  1147.                {6, 6,14,10, 2},\
  1148.                {6, 6,14,10, 2},\
  1149.                {6, 6,14,10, 2},\
  1150.                {6, 6,14,10, 2},\
  1151.                {6, 6,14,10, 2},\
  1152.                {6, 6,14,10, 2},\
  1153.                {6, 6,14,10, 2},\
  1154.                {6, 6,14,10, 2}}
  1155. /*****************************************************************   
  1156.   STRATUS.H --     Header file for stratus cloud template
  1157. ****************************************************************/
  1158.  
  1159. #define NPOINTS 6    /* Number of points on the "parent" polygon */
  1160. #define NTRANS  5    /* Number of transformed "children" */
  1161. #define NLEVELS 5    /* Number of levels to draw */
  1162. #define COUNT 10000  /* Number of dots to paint */
  1163. #define CENTERX 320  /* Center of the screen */
  1164. #define CENTERY 240
  1165. #define SEEDX 40,80,40,-40,-80,-40  /* The "parent" polygon */
  1166. #define SEEDY 22,-2,-22,-22,2,22
  1167.  
  1168. /* The tranformations which define the "children" */
  1169. #define MOVEX -70,-44,45,60,-3.3  /* Displacement */
  1170. #define MOVEY 11,-34,-31,1.6,42
  1171. #define SIZEX   .75,.43,.38,.75,.8    /* Size change */
  1172. #define SIZEY   .45,.47,.44,.61,.2
  1173. #define SPINX   6.3,6.3,6.3,6.3,0    /* Rotation */
  1174. #define SPINY   6.3,6.3,6.3,6.3,6.3
  1175.  
  1176. #define PALETTE {_BLACK, _RED, _GREEN, _CYAN, \
  1177.         _BLUE, _MAGENTA, _BROWN, _WHITE, \
  1178.         _GRAY, _LIGHTBLUE, _LIGHTGREEN, _LIGHTCYAN, \
  1179.         _LIGHTRED, _LIGHTMAGENTA, _LIGHTYELLOW, _BRIGHTWHITE}
  1180.  
  1181. #define COLOR {{15,15,15, 7, 8},\
  1182.                {15,15,15,15,15},\
  1183.                {15,15,15,15,15},\
  1184.                {15,15,15,15,15},\
  1185.                {15,15,15,15,15},\
  1186.                {15,15,15,15,15},\
  1187.                {15,15,15,15,15},\
  1188.                {15,15,15,15,15},\
  1189.                {15,15,15,15,15}}
  1190. /*****************************************************************
  1191.    ZOOM.H --   Header file for abstract zooming artwork template
  1192.      Note that this very simple template creates a visually complex image,
  1193.      while seemingly simple linear forms like the cartoon mouse require
  1194.      much more work and information to express as fractals.  When drawing
  1195.      with fractals, richly detailed trees are simpler and easier to create
  1196.      than smooth objects like tables and chairs!
  1197. *****************************************************************/
  1198.  
  1199. #define NPOINTS 5    /* Number of points on the "parent" polygon */
  1200. #define NTRANS  5    /* Number of transformed "children" */
  1201. #define NLEVELS 4    /* Number of levels to draw */
  1202. #define COUNT 20000  /* Number of dots to paint */
  1203. #define CENTERX 320  /* Center of the screen */
  1204. #define CENTERY 340
  1205. #define SEEDX -66,-334,60,272,66
  1206. #define SEEDY -7,100,-120,-27,55
  1207.  
  1208. /* The tranformations which define the "children" */
  1209.  
  1210. #define MOVEX 55,104,185,30,-45
  1211. #define MOVEY -309,-1,-50,28,-25
  1212. #define SIZEX .27,.36,.5,.28,.98
  1213. #define SIZEY .27,.27,.18,.21,.5
  1214. #define SPINX 4.71,3.88,3.34,4.3,6
  1215. #define SPINY 2.48,.93,.39,1.16,6
  1216.  
  1217. #define PALETTE {_BLUE, _RED, _GREEN, _CYAN, \
  1218.                 _BLACK, _MAGENTA, _BROWN, _WHITE, \
  1219.         _GRAY, _LIGHTBLUE, _LIGHTGREEN, _LIGHTCYAN, \
  1220.         _LIGHTRED, _LIGHTMAGENTA, _LIGHTYELLOW, _BRIGHTWHITE}
  1221.  
  1222. #define COLOR {{15,15,15,15},\
  1223.                {14,14,14,14},\
  1224.                {14,14,14,14},\
  1225.                {14,14,14,14},\
  1226.                {14,14,14,14},\
  1227.                {15,15,15,15},\
  1228.                {15,15,15,15}}
  1229.