home *** CD-ROM | disk | FTP | other *** search
/ Virtual Reality Zone / VRZONE.ISO / mac / PC / REND386 / UTILS / MOUNTAIN / MOUNTAIN.C < prev    next >
C/C++ Source or Header  |  1993-02-23  |  4KB  |  164 lines

  1. /* Make a 3D mountain range using Brownian motion, size (xdim,ydim) and output
  2.    in plg file format to mount.plg 
  3.    
  4.    By Michael Snoswell *no* Copyright Jan 1993
  5.    michaels@vsl.com.au
  6.    
  7.    Use as you will, but a mention would be nice in your achnowledgments.
  8.    
  9.    Written initially to create test objects for Cyberterm.
  10.    
  11.    "Tell us how it works!"
  12.    
  13.    Well, start in the middle, and go for a random 2D walk until you reach the
  14.    iterations max. For each point traversed, increment the array element, this
  15.    becomes the mountain height. If you reach the edge of the grid, then start
  16.    again somewhere near the middle.
  17.    The array is treated in a slightly tricky way
  18.    so that it is divided into a hexagonal grid. The triangles and then read
  19.    off and written out to the plg file. Simple! 
  20. */
  21.  
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24.  
  25. int xdim = 15;
  26. int ydim = 15;
  27. int max_iter = 2000;
  28. int scale = 100;
  29. int colour = 4;
  30. int height_scale = 1;
  31.  
  32. int mnt[100][100]; /* makes it easy this way for the moment, change to dynamic
  33.                       if I get time! */
  34. FILE *fp;
  35.  
  36. int main()
  37. {
  38. int y, x;
  39. int xoffset;
  40. int xmax;
  41. int iter;
  42. int dx, dy;
  43. int c1, c2;
  44.  
  45.   /* find the middle place to start */
  46.   x = xdim / 2;
  47.   y = ydim / 2;
  48.   
  49.   /* make the mountain */
  50.   for ( iter = 0; iter < max_iter; iter++ )
  51.   {
  52.     /* move random direction, if overshoot edge, then try again */
  53.     dy = y; dx = x;
  54.     switch (rand() % 6)
  55.     {
  56.       case 0:dy--;       break;
  57.       case 1:dy--; dx++; break;
  58.       case 2:      dx--; break;
  59.       case 3:      dx++; break;
  60.       case 4:dy++;       break;
  61.       case 5:dy++; dx++; break;
  62.     }
  63.     /* if we've hit the edge, reset to somewhere near the middle */
  64.     if (dy < 0 || dx < 0 || dy >= ydim || dx >= xdim)
  65.     {
  66.       dx = xdim / 2 + (rand() % (xdim / 4) - (xdim / 4));
  67.       dy = ydim / 2 + (rand() % (ydim / 4) - (ydim / 4));
  68.     }
  69.     y = dy; x = dx;
  70.     mnt[y][x]++;
  71.   }
  72.  
  73.   /* write it out */
  74.   fp = fopen("mount.plg", "wt");
  75.  
  76.   /* write out number of points and number of polygons (triangles) */
  77.   fprintf(fp, "mountain %d %d\n\n", xdim * ydim, (2*xdim-4) * (ydim-1) );
  78.  
  79.   /* write out the points (not all used, but this is the easiest way to
  80.      do this without my having to think too hard! */
  81.   for ( y = 0; y < ydim; y++ )
  82.   {
  83.     /* even rows are staggered by scale/2 to the right, to make triangles */
  84.     if (y % 2 == 0)
  85.       xoffset = scale / 2;
  86.     else
  87.       xoffset = 0;
  88.       
  89.     for ( x = 0; x < xdim; x++ )
  90.       fprintf(fp, "%d %d %d\n", 
  91.                   (scale * x) + xoffset - (scale * (xdim / 2)), 
  92.           height_scale * mnt[y][x],
  93.           (scale * y) - (scale * (ydim / 2)));
  94.   }
  95.  
  96.   fprintf(fp, "\n");
  97.  
  98.   /* Now write out the triangles, all same colour for the moment */
  99.   for ( y = 0; y < ydim; y++ )
  100.   {
  101.     /* even rows are a bit different */
  102.     if (y % 2 == 0)
  103.       for ( x = 0; x < xdim - 2; x++ )
  104.       {
  105.     c1 = 1 + rand() % 15;
  106.     c2 = 1 + rand() % 15;
  107.     /* These bits make double side triangles so you cant see through mnt
  108.        from underneath
  109.     fprintf(fp, "0x1%1XFF 3 %d %d %d\n", 
  110.              c1,
  111.              y * xdim + x,
  112.              (y+1) * xdim + x,
  113.              (y+1) * xdim + x + 1);
  114.     fprintf(fp, "0x1%1XFF 3 %d %d %d\n", 
  115.              c2,
  116.              y * xdim + x,
  117.              (y+1) * xdim + x + 1,
  118.              y * xdim + x + 1);
  119.     */
  120.     fprintf(fp, "0x1%1XFF 3 %d %d %d\n", 
  121.              c1,
  122.              y * xdim + x,
  123.              (y+1) * xdim + x + 1,
  124.              (y+1) * xdim + x);
  125.     fprintf(fp, "0x1%1XFF 3 %d %d %d\n", 
  126.              c2,
  127.              y * xdim + x,
  128.              y * xdim + x + 1,
  129.              (y+1) * xdim + x + 1);
  130.       }
  131.     else
  132.       for ( x = 0; x < xdim - 2; x++ )
  133.       {
  134.     c1 = 1 + rand() % 15;
  135.     c2 = 1 + rand() % 15;
  136.     /* And the double triangles again...
  137.     fprintf(fp, "0x1%1XFF 3 %d %d %d\n", 
  138.              c1,
  139.              y * xdim + x,
  140.              (y+1) * xdim + x,
  141.              y * xdim + x + 1);
  142.     fprintf(fp, "0x1%1XFF 3 %d %d %d\n", 
  143.              c2,
  144.              y * xdim + x + 1,
  145.              (y+1) * xdim + x,
  146.              (y+1) * xdim + x + 1);
  147.     */
  148.     fprintf(fp, "0x1%1XFF 3 %d %d %d\n", 
  149.              c1,
  150.              y * xdim + x,
  151.              y * xdim + x + 1,
  152.              (y+1) * xdim + x);
  153.     fprintf(fp, "0x1%1XFF 3 %d %d %d\n", 
  154.              c2,
  155.              y * xdim + x + 1,
  156.              (y+1) * xdim + x + 1,
  157.              (y+1) * xdim + x);
  158.       }
  159.   }
  160.   fclose(fp);
  161.   return(1);
  162. }
  163.  
  164.