#### Archived

This topic is now archived and is closed to further replies.

# fault line formation generation method

This topic is 5482 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

void aperfil_01(float *band, int stride, int icount, float filter)
{
float v=band[0];
int j = stride;
int i;
for(i=0;i < icount-1;i++)
{
band[j]=((filter*v)+((1-filter)*band[j]));
v=band[j];
j+=stride;
}
}
float **fault_formation_f(int width,int height,int low,int high,int iterations,float filter)
{
float **points=new float*[width];
for(int i=0;i < width;i++)
{
points[ i ]=new float[height];
}
for(int ax=0;ax < width;ax++)
{
for(int ay=0;ay 0)
{
int ttheight=high-((high-low)*iterations)/totiterations;
int randx1,randy1,randx2,randy2;
randx1=rangerand(0,width);
randx2=rangerand(0,width);
randy1=rangerand(0,height);
randy2=rangerand(0,height);

int dirx1,diry1,dirx2,diry2;
dirx1=randx2-randx1;
diry1=randy2-randy1;

for(ix=0;ix < width;ix++)
{
for(iy=0;iy < height;iy++)
{
dirx2=ix-randx1;
diry2=iy-randy1;
if((dirx2*diry1 - dirx1*diry2) > 0)
{
points[ix][iy]=ttheight+points[ix][iy];
}
}
}
iterations--;
}
return points;
}

basically, the above is an implementation of the fault line formation method of generation terrain. That first function there is the erosion function... Supposedly, after each fault is placed, you're supposed to filter the entire map 4 times, one per direction (north, south, east, west) thats top to bottom, bottom to top, left to right, right to left im not sure on how to do this, i think ive got top to bottom and bottom to top correct, it goes something like aperfil_01(points[ix],1,128,0.4f); aperfil_01(points[width-1-ix],1,128,0.4f); where ix is a number going from 0 to 127, and width is 128 it doesnt like me guys, im telling you, i dont know how to go left to right or right to left... could someone help me who's tried implementing this before? [edited by - fireking on November 15, 2003 8:53:05 AM] [edited by - fireking on November 15, 2003 8:53:45 AM]

anyone?

bump

##### Share on other sites
surely someone knows a little something about erosion formulas

##### Share on other sites
possibly telling whats wrong could be a great help, not? memory access errors? wrong results? i''ve read carefully your text, not the source as its uncommented anyways (so there is no // <-- crash here anywhere:D).

If that''s not the help you''re after then you''re going to have to explain the problem better than what you have. - joanusdmentia

davepermen.net

##### Share on other sites
Like this?

void FilterBand(float *band,int stride,int count,float filter){ int i,j=stride; float v = band[0]; for (i=0;i<count-1;i++) {  band[j] = (filter*v + (1-filter)*band[j]);  v = band[j];  j+=stride; }}/*Erosion filter -Erodes a height field in all 4 directions*/void FilterHeightField(float *field,int size,float filter){ int i; /* Erode rows left to right */ for (i=0;i<size;i++) {  FilterBand(&field[size*i],1,size,filter); } /* Erode rows right to left */ for (i=0;i<size;i++) {  FilterBand(&field[size*i+size-1],-1,size,filter); } /* Erode columns top to bottom */ for (i=0;i<size;i++) {  FilterBand(&field[i],size,size,filter); } /* Erode columns bottom to top */ for (i=0;i<size;i++) {  FilterBand(&field[size*(size-1)+i],-size,size,filter); }}

EDIT: Assumes a square height map.
EDIT AGAIN: Change ints to floats.

Josh
vertexnormal AT linuxmail DOT org

Check out Golem: Lands of Shadow, an isometrically rendered hack-and-slash inspired equally by Nethack and Diablo.

[edited by - VertexNormal on November 17, 2003 8:04:01 PM]

[edited by - VertexNormal on November 17, 2003 8:07:37 PM]

##### Share on other sites
@ VertexNormal

The terrain is in the form of a 2 dimensional array...

@ everyone else

the problem is, i dont know how to pass terrain[x][y] into FilterStuff(somepointer,...)

basically, i have a function without the documentation, and since i know erosion is a common topic in terrain generation, i was hoping someone has seen this function somewhere, and would know how to use it...

i need to pass some sort of 1d array to the function, several times, in order to erode the fractal generated terrain...

##### Share on other sites
It's basically the same as what I posted, except you have to index the beginning of a band differently, and modify your stride.

Basically, the filter takes a pointer to an array of floats. It knows nothing of how the array is set up, or how the array is indexed. Stride tells it how to increment the current position in the array to get the next position in the band being filtered.

In an array that is indexed such as HeightMap[width][height], then the stride for a row is equal to 1 or -1 (depending on left to right or right to left) and the stride for a column is height or -height (depending on top to bottom or bottom to top). In this case, rows are indexed [ i ][ 0 ] to [ i ][height-1] and columns are indexed [ 0 ][ i ] to [ width-1 ][ i ]. In this context, a row is of length height and is enumerated on the first subscript, while a column is of length width and is enumerated on the second subscript.

(Note: This is why I prefer to index a 2D array like this as HeightMap[ height ][ width ]. That way, the width subscript enumerates columns, and the height subscript enumerates rows; ie, rows are indexed with y and columns are indexed with x. Just a personal preference, but it is the reason for any mistakes in the coming code, as I am having to turn my thinking sideways to think in terms of indexing [ width ][ height ]. So please, forgive me if I made any errors.)

So, to filter all rows from left to right, we need to iterate through all of the rows (0..width), and take the address of the element at the beginning of each row ( [ i ][ 0 ] ). The stride in this case will be +1, as the elements in the row are organized: [ i ][ 0 ], [ i ][ 1 ], [ i ][ 2 ] etc...
for(i=0; i< width; i++){ FilterBand((float *)&HeightMap[ i ][ 0 ], 1, height, filter);}

To filter right to left, we need to take the address of the element at the END of each row(height-1), and apply a stride of -1 (as the elements in this band are ordered [ i ][ height-1 ], [ i ][ height-2 ], etc...).
for(i=0; i< width; i++){ FilterBand((float *)&HeightMap[ i ][ height-1 ], -1, height, filter);}

To filter from top to bottom, we need to iterate on columns (0..height) and take the address at the beginning of each column. In this case, stride will be equal to height (which is the width in sequential elements of each row of your 2D array.) Adding this moves us down a row, to the next element in the band.
for(i=0; i< height; i++){ FilterBand((float *)&HeightMap[ 0 ][ i ], height, width, filter);}

And conversely, filtering from bottom to top we take the address at the end of each column, and a stride of -height.
for(i=0; i< height; i++){ FilterBand((float *)&HeightMap[ width-1 ][ i ], -height, width, filter);}

These snippets should work for your height map. If not, forgive me for any errors.

Good luck, and if you still need help or if I confused you further, don't hesitate to ask.

EDIT: Fix some code mangled by forum/HTML tag interpretation.

Josh
vertexnormal AT linuxmail DOT org

Check out Golem: Lands of Shadow, an isometrically rendered hack-and-slash inspired equally by Nethack and Diablo.

[edited by - VertexNormal on November 18, 2003 2:41:41 PM]

##### Share on other sites
damnit, that doesnt work either...

Unhandled exception at 0x77e73887 in createworld.exe: Microsoft C++ exception: std::bad_alloc @ 0x0012fb58.

im just going to buy the freaking book, thanks for the help anyways...

##### Share on other sites
Hmmm... I tested it, and it worked fine. Are you sure the problem isn't somewhere else?

EDIT: Looking more closely at your heightmap generator, it looks like the problem is probably coming from the way you are allocating your height map. You are allocating as an array of separate arrays; the code I posted expects the heightmap to be a single block.

If you want to allocate as an array of arrays, you will have to change the filtering function completely, as you can not expect the arrays to be allocated sequentially. This filtering method (and any algorithm that works with a striding parameter) expects all of the data to be allocated sequentially in memory, rather than as an array of arrays, whose separate arrays could be located just about anywhere.

Modify your heightmap allocation to ensure that the entire map is allocated sequentially in a predictable fashion, and it should work.

Josh
vertexnormal AT linuxmail DOT org

Check out Golem: Lands of Shadow, an isometrically rendered hack-and-slash inspired equally by Nethack and Diablo.

[edited by - VertexNormal on November 18, 2003 7:37:36 PM]

1. 1
Rutin
71
2. 2
3. 3
4. 4
5. 5

• 21
• 10
• 33
• 20
• 9
• ### Forum Statistics

• Total Topics
633428
• Total Posts
3011822
• ### Who's Online (See full list)

There are no registered users currently online

×