home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Virtual Reality Zone
/
VRZONE.ISO
/
mac
/
PC
/
REND386
/
UTILS
/
MOUNTAIN
/
MOUNTAIN.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-02-23
|
4KB
|
164 lines
/* Make a 3D mountain range using Brownian motion, size (xdim,ydim) and output
in plg file format to mount.plg
By Michael Snoswell *no* Copyright Jan 1993
michaels@vsl.com.au
Use as you will, but a mention would be nice in your achnowledgments.
Written initially to create test objects for Cyberterm.
"Tell us how it works!"
Well, start in the middle, and go for a random 2D walk until you reach the
iterations max. For each point traversed, increment the array element, this
becomes the mountain height. If you reach the edge of the grid, then start
again somewhere near the middle.
The array is treated in a slightly tricky way
so that it is divided into a hexagonal grid. The triangles and then read
off and written out to the plg file. Simple!
*/
#include <stdio.h>
#include <stdlib.h>
int xdim = 15;
int ydim = 15;
int max_iter = 2000;
int scale = 100;
int colour = 4;
int height_scale = 1;
int mnt[100][100]; /* makes it easy this way for the moment, change to dynamic
if I get time! */
FILE *fp;
int main()
{
int y, x;
int xoffset;
int xmax;
int iter;
int dx, dy;
int c1, c2;
/* find the middle place to start */
x = xdim / 2;
y = ydim / 2;
/* make the mountain */
for ( iter = 0; iter < max_iter; iter++ )
{
/* move random direction, if overshoot edge, then try again */
dy = y; dx = x;
switch (rand() % 6)
{
case 0:dy--; break;
case 1:dy--; dx++; break;
case 2: dx--; break;
case 3: dx++; break;
case 4:dy++; break;
case 5:dy++; dx++; break;
}
/* if we've hit the edge, reset to somewhere near the middle */
if (dy < 0 || dx < 0 || dy >= ydim || dx >= xdim)
{
dx = xdim / 2 + (rand() % (xdim / 4) - (xdim / 4));
dy = ydim / 2 + (rand() % (ydim / 4) - (ydim / 4));
}
y = dy; x = dx;
mnt[y][x]++;
}
/* write it out */
fp = fopen("mount.plg", "wt");
/* write out number of points and number of polygons (triangles) */
fprintf(fp, "mountain %d %d\n\n", xdim * ydim, (2*xdim-4) * (ydim-1) );
/* write out the points (not all used, but this is the easiest way to
do this without my having to think too hard! */
for ( y = 0; y < ydim; y++ )
{
/* even rows are staggered by scale/2 to the right, to make triangles */
if (y % 2 == 0)
xoffset = scale / 2;
else
xoffset = 0;
for ( x = 0; x < xdim; x++ )
fprintf(fp, "%d %d %d\n",
(scale * x) + xoffset - (scale * (xdim / 2)),
height_scale * mnt[y][x],
(scale * y) - (scale * (ydim / 2)));
}
fprintf(fp, "\n");
/* Now write out the triangles, all same colour for the moment */
for ( y = 0; y < ydim; y++ )
{
/* even rows are a bit different */
if (y % 2 == 0)
for ( x = 0; x < xdim - 2; x++ )
{
c1 = 1 + rand() % 15;
c2 = 1 + rand() % 15;
/* These bits make double side triangles so you cant see through mnt
from underneath
fprintf(fp, "0x1%1XFF 3 %d %d %d\n",
c1,
y * xdim + x,
(y+1) * xdim + x,
(y+1) * xdim + x + 1);
fprintf(fp, "0x1%1XFF 3 %d %d %d\n",
c2,
y * xdim + x,
(y+1) * xdim + x + 1,
y * xdim + x + 1);
*/
fprintf(fp, "0x1%1XFF 3 %d %d %d\n",
c1,
y * xdim + x,
(y+1) * xdim + x + 1,
(y+1) * xdim + x);
fprintf(fp, "0x1%1XFF 3 %d %d %d\n",
c2,
y * xdim + x,
y * xdim + x + 1,
(y+1) * xdim + x + 1);
}
else
for ( x = 0; x < xdim - 2; x++ )
{
c1 = 1 + rand() % 15;
c2 = 1 + rand() % 15;
/* And the double triangles again...
fprintf(fp, "0x1%1XFF 3 %d %d %d\n",
c1,
y * xdim + x,
(y+1) * xdim + x,
y * xdim + x + 1);
fprintf(fp, "0x1%1XFF 3 %d %d %d\n",
c2,
y * xdim + x + 1,
(y+1) * xdim + x,
(y+1) * xdim + x + 1);
*/
fprintf(fp, "0x1%1XFF 3 %d %d %d\n",
c1,
y * xdim + x,
y * xdim + x + 1,
(y+1) * xdim + x);
fprintf(fp, "0x1%1XFF 3 %d %d %d\n",
c2,
y * xdim + x + 1,
(y+1) * xdim + x + 1,
(y+1) * xdim + x);
}
}
fclose(fp);
return(1);
}