home *** CD-ROM | disk | FTP | other *** search
/ Graphics 16,000 / graphics-16000.iso / amiga / fractal / fcloud.arc / cloud.c < prev    next >
C/C++ Source or Header  |  1989-11-05  |  5KB  |  201 lines

  1. /***************************************************************/
  2. /*                                                             */
  3. /*  FractalCloud version 0.9 (not promising anything!)         */
  4. /*  (c) 1989 by Philip MacGovern                               */
  5. /*              3433 1st ave. San Diego, CA 92103              */
  6. /*                                                             */
  7. /*  These routines are freeware, fully public domain           */
  8. /*                                                             */
  9. /***************************************************************/
  10. #include <exec/types.h>
  11. #include <intuition/intuition.h>
  12. #include <stdio.h>
  13. #include <math.h>
  14. #define NumWeWant 128
  15. #define MaxLevel 7
  16.  
  17. typedef float row[NumWeWant+1];
  18. row *X;
  19.  
  20. struct Window *make_window();
  21. struct Screen *make_screen();
  22. struct IntuiMessage *GetMsg();
  23. double Gauss();
  24. void MidPointFM2D();
  25. float f3();
  26. float f4();
  27.  
  28. float f3(delta,x0,x1,x2)
  29. float delta;
  30. float x0,x1,x2;
  31. {
  32.     return((float)((x0+x1+x2)/3.0 + delta*Gauss()));
  33. }
  34.  
  35. float f4(delta,x0,x1,x2,x3)
  36. float delta;
  37. float x0,x1,x2,x3;
  38. {
  39.     return((float)((x0+x1+x2+x3)/4.0 + delta*Gauss()));
  40. }
  41.  
  42. /* MidPointFM2D will get fractal motion in two dimensions with the midpoint
  43.                 displacement method with successive random additions 
  44. */
  45. void MidPointFM2D(maxlevel,sigma,H,addition,seed)
  46. SHORT maxlevel,addition;
  47. float sigma,H;
  48. unsigned int seed;
  49. {
  50.     int N,stage;
  51.     float delta;
  52.     int x,y,D,d;
  53.  
  54.     sigma = 0.5;
  55.     InitGauss((unsigned)seed);
  56.     delta = sigma;
  57.     N = (int)pow2((double)maxlevel);
  58.     X[0][0] = (float)delta * Gauss();
  59.     X[0][N] = (float)delta * Gauss();
  60.     X[N][N] = (float)delta * Gauss();
  61.     X[N][0] = (float)delta * Gauss();
  62.     D = N;
  63.     d = N/2;
  64.     for(stage = 1;stage <= maxlevel; stage ++) {
  65.         delta = delta * (float)pow(0.5,0.5*H);
  66.         for(x=d;x<=(N-d);x+=D) 
  67.             for(y=d;y<=(N-d);y+=D)
  68.                 X[x][y] = f4(delta,X[x+d][y+d],X[x+d][y-d],X[x-d][y+d],X[x-d][y-d]);
  69.         if(addition)
  70.             for(x=0;x<=N;x+=D)
  71.                 for(y=0;y<=N;y+=D)
  72.                     X[x][y] += (float)delta * Gauss();
  73.         delta = delta * (float)pow(0.5,0.5*H);
  74.         for(x=d;x<=(N-d);x+=D) {
  75.             X[x][0] = f3(delta,X[x+d][0],X[x-d][0],X[x][d]);
  76.             X[x][N] = f3(delta,X[x+d][N],X[x-d][N],X[x][N-d]);
  77.             X[0][x] = f3(delta,X[0][x+d],X[0][x-d],X[d][x]);
  78.             X[N][x] = f3(delta,X[N][x+d],X[N][x-d],X[N-d][x]);
  79.         }
  80.         for(x=d;x<=(N-d);x+=D) 
  81.             for(y=D;y<=(N-d);y+=D)
  82.                 X[x][y] = f4(delta,X[x][y+d],X[x][y-d],X[x+d][y],X[x-d][y]);
  83.         for(x=D;x<=(N-d);x+=D) 
  84.             for(y=d;y<=(N-d);y+=D)
  85.                 X[x][y] = f4(delta,X[x][y+d],X[x][y-d],X[x+d][y],X[x-d][y]);
  86.         if(addition) {
  87.             for(x=0;x<=N;x+=D)
  88.                 for(y=0;y<=N;y+=D)
  89.                     X[x][y] += (float)delta * Gauss();
  90.             for(x=d;x<=(N-d);x+=D) 
  91.                 for(y=d;y<=(N-d);y+=D)
  92.                     X[x][y] += (float)delta * Gauss();
  93.         }
  94.         D = D / 2;
  95.         d = d / 2;
  96.     }    
  97. }
  98.  
  99. void Set_Colors(vp,c)
  100. struct ViewPort *vp;
  101. UBYTE c[15][3];
  102. {
  103.     int n;
  104.     
  105.     for(n=0;n<15;n++)
  106.         SetRGB4(vp,n+3,c[n][0],c[n][1],c[n][2]);
  107. }
  108.  
  109. /* main() will open a screen, window, and draw (hopefully) some Fractal
  110.           motion by whatever method we are using */
  111. main(argc,argv)
  112. int argc;
  113. char **argv;
  114. {
  115.     struct Window *win;
  116.     struct Screen *scrn;
  117.     struct RastPort *rport;
  118.     struct ViewPort *vport;
  119.     struct IntuiMessage *msg;
  120.     ULONG flags = ACTIVATE | WINDOWDEPTH | WINDOWDRAG |
  121.                     WINDOWCLOSE | SMART_REFRESH ;
  122.     int n = NumWeWant;
  123.     float sigma;
  124.     int a;
  125.     USHORT clock[2];    
  126.     SHORT i,j;
  127.     float H;
  128.     UBYTE colList[11] = { 3, 5, 7, 9, 11, 12, 13, 14, 15, 16, 17 };
  129.     UBYTE colors[15][3] =
  130.         { { 0, 0, 15 },
  131.           { 1, 1, 15 },
  132.           { 2, 2, 15 },
  133.           { 3, 3, 15 },
  134.           { 4, 4, 15 },
  135.           { 5, 5, 15 },
  136.           { 6, 6, 15 },
  137.           { 7, 7, 15 },
  138.           { 8, 8, 15 },
  139.           { 9, 9, 15 },
  140.           { 10, 10, 15 },
  141.           { 11, 11, 15 },
  142.           { 12, 12, 15 },
  143.           { 13, 13, 15 },
  144.           { 14, 14, 15 } };
  145.  
  146.     if((X = (row *)calloc(NumWeWant+1,sizeof(row)))==NULL) {
  147.         printf("\nUnable to allocate memory\n");
  148.         exit(FALSE);
  149.     }
  150.     if(argc>1) 
  151.         H = atof(argv[1]);                /* H = fractal dimension */
  152.         if(H>=1.0 || H<=0.0) {
  153.             printf("\nUsing H (=3-D) = 0.5\n");
  154.             H = 0.5;
  155.         }    
  156.     else {
  157.         printf("\nUsing H (=3-D) = 0.5\n");
  158.         H = 0.5;
  159.     }
  160.     sigma = 0.5;                        /* initial s.d. */
  161.     timer(clock);
  162.     Open_All();                            /* open the intuition.library */
  163.     scrn = make_screen(0,320,200,5,0x00,0x01,NULL,"FractalClouds v0.9 - Generating");
  164.     if(scrn==NULL) {
  165.         Close_All();
  166.         exit(FALSE);
  167.     }
  168.     win = make_window(30,30,NumWeWant,NumWeWant+10,NULL,flags,-1,-1,scrn);
  169.     if(win==NULL) {
  170.         Close_All();
  171.         CloseScreen(scrn);
  172.         exit(FALSE);
  173.     }
  174.     vport = &scrn->ViewPort;
  175.     Set_Colors(vport,colors);
  176.     rport = win->RPort;
  177.     /* Change the FALSE to TRUE if you want random additions */
  178.     MidPointFM2D(MaxLevel,sigma,H,FALSE,clock[1]);
  179.     SetWindowTitles(win,NULL,"FractalClouds v0.9 - Displaying");
  180.     for(i=0;i<n;i++)
  181.         for(j=0;j<n;j++) {
  182.             SetAPen(rport,3);
  183.             a = (int)(X[i][j]*10.0);
  184.             if(a>=-1&&a<=9) SetAPen(rport,colList[a+1]);
  185.             Move(rport,i,j+10);
  186.             Draw(rport,i,j+10);
  187.         }
  188.     SetWindowTitles(win,NULL,"FractalClouds v0.9 - Close to Quit");
  189.     for(;;) {                                    /* wait 'til user closes */
  190.         Wait(1<<win->UserPort->mp_SigBit);
  191.         while((msg=GetMsg(win->UserPort))) {
  192.             if(msg->Class == CLOSEWINDOW) {
  193.                 ReplyMsg(msg);
  194.                 CloseWindow(win);
  195.                 CloseScreen(scrn);
  196.                 Close_All();
  197.                 exit(NULL);
  198.             }
  199.         }
  200.     }
  201. }