• Create Account

### #ActualRiztro

Posted 27 December 2012 - 08:10 PM

Your seed is always the same... Always 57/17.
-What is the reason behind it, I wonder?

You're calling srand all time. -You should only be calling it once (it keeps the following numbers the same for every time it's invoked with the same seed. The behaviours you're experiencing is familiar to when i did it years ago.
To elaborate on SuperVGA, this line is the line that is fishy:

srand((iseed*57)/(iseed*17));

The iseed in the numerator is cancelled by the iseed in the denominator, causing the seed to always be 57/17, or 3, when the island mask is generated.

Thankyou for pointing that out! I have fixed that but now I am still getting similar maps.. :/. I am sure changing that helps though

I'd rebuild it, piece by piece.  That's obviously terrible advice, but its honestly what I would do.

Although I didn't look at your code, you might try this:
You might want to generate a constant perlin noise and a random location, instead of a random perlin noise and a constant location.

Also try adjusting the map maximums to some number which is coprime to the number you're using right now.  Avoid Mersenne numbers.  If that doesn't work, try again with a number coprime to both of those.  You might be generating a specific repeating pattern or something.  Well, no, the map would be offset I suppose.

Not sure.  Simplify and try to generate more basic structures.  Try to make those diverse.  Then add more depth.

Change each number one by one dude.  It's either a specific algorithm or a specific constant that's throwing you off.

I got lost at your third paragraph :/ Can you please elaborate on the thing that I should also try adjusting

I just got done playing with his code. I took out the multiple calls to srand (now a single call: srand(iseed);), the do nothing for loop and various other oddities ((2 / 1) ?). It now creates very regular terrains. The generated terrains show a very strong rotational symmetry. Each 1/4 of the image is nearly an exact copy of each other, rotated 90°.

I think the entire algorithm needs to be rewritten.

Sorry yeah the (2/1) thing gets the numbers into the range of -1 and 1. The 1 in that equation is the max number in the set of numbers. And what algorithm needs to be rewritten, the island masking one? :/ Because if that is so, I have no clue what to do. I just followed what this guy said he did on his blog.

The algorithm used looks like the same from: http://breinygames.blogspot.nl/2012/06/generating-terrain-using-perlin-noise.html

Just playing around a little (I did change some code so I could more easily read it), here is what I came up with:

//Little program to generate test map with only 0 and 1 tile

#include <iostream>
#include <noise/noise.h>
#include "noiseutils.h"
#include <stdlib.h>
#include <string>
#include <sstream>

using namespace std;
using namespace noise;

template <typename T> string tostring (T v) {
ostringstream ss;
ss << v;
return ss.str();
}

void generate_island(int iseed) {
module::Perlin myModule;

myModule.SetSeed (iseed);
utils::NoiseMap heightMap;
utils::NoiseMapBuilderPlane heightMapBuilder;
heightMapBuilder.SetSourceModule(myModule);
heightMapBuilder.SetDestNoiseMap(heightMap);
heightMapBuilder.SetDestSize(512, 512);
heightMapBuilder.SetBounds(2.0, 6.0, 1.0, 5.0);
heightMapBuilder.Build();

float islandMap[512][512];
srand(iseed);

for (int count = 0; count < 1; count++ ){
//Initialize values for a new map
for (int i = 0; i < 512; i++) {
for (int j = 0; j < 512; j++) {
islandMap[j][i] = 0;
}
}

//Choose a random location, travel in random directions
int x = 0, y = 0;
float previous = 0;

for (int i = 0; i < 1000000; i++) {
if(y == 511 || y == 0 || x == 511 || x == 0) {
x = rand() % 512;
y = rand() % 512;
}

if(previous >= islandMap[x][y]) {
islandMap[x][y] += 1;
}

previous = islandMap[x][y];

switch(rand() % 4) {
case 0:
x -= 1;
break;
case 1:
y -= 1;
break;
case 2:
x += 1;
break;
case 3:
y += 1;
break;
default:
break;
}
}

//find max value for normalizing
for (int i = 0; i < 512; i++) {
for (int j = 0; j < 512; j++) {
islandMap[i][j] = islandMap[i][j] * 2 - 1;
}
}

int max = 0;
int min = 0;
for (int i = 0; i < 512; i++) {
for (int j = 0; j < 512; j++) {
if(max < islandMap[i][j]) {
max = islandMap[i][j];
}

if(min > islandMap[i][j]) {
min = islandMap[i][j];
}
}
}

//Multiply values of original by new maps generated
for (int i = 0; i < 512; i++) {
for (int j = 0; j < 512; j++) {
float islandValue = (islandMap[i][j] - min) / (max - min);
float mapValue = (heightMap.GetValue(i, j) + 1) / 2;
float newValue = 2 * islandValue * mapValue - 1;
heightMap.SetValue(i, j, newValue);
}
}
}

utils::RendererImage renderer;
utils::Image image;
renderer.SetSourceNoiseMap (heightMap);
renderer.SetDestImage (image);
renderer.EnableLight ();
renderer.SetLightContrast (3.0);
renderer.SetLightBrightness (2.0);
renderer.Render ();

utils::WriterBMP writer;
writer.SetSourceImage (image);
writer.SetDestFilename ("tutorial" + tostring(iseed) + ".bmp");
writer.WriteDestFile ();
}

int main() {
for(int i=0; i<10; ++i){
generate_island(i);
}
return 0;
}


Thankyou very much for this! I like the randomness and I love the code but do you know if there is any way to make it less "holey". There are specks of water all over the terrain and what I am going for is more of a solid island surrounded by water

### #2Riztro

Posted 27 December 2012 - 08:09 PM

Your seed is always the same... Always 57/17.
-What is the reason behind it, I wonder?

You're calling srand all time. -You should only be calling it once (it keeps the following numbers the same for every time it's invoked with the same seed. The behaviours you're experiencing is familiar to when i did it years ago.
To elaborate on SuperVGA, this line is the line that is fishy:

srand((iseed*57)/(iseed*17));

The iseed in the numerator is cancelled by the iseed in the denominator, causing the seed to always be 57/17, or 3, when the island mask is generated.

Thankyou for pointing that out! I have fixed that but now I am still getting similar maps.. :/. I am sure changing that helps though

I'd rebuild it, piece by piece.  That's obviously terrible advice, but its honestly what I would do.

Although I didn't look at your code, you might try this:
You might want to generate a constant perlin noise and a random location, instead of a random perlin noise and a constant location.

Also try adjusting the map maximums to some number which is coprime to the number you're using right now.  Avoid Mersenne numbers.  If that doesn't work, try again with a number coprime to both of those.  You might be generating a specific repeating pattern or something.  Well, no, the map would be offset I suppose.

Not sure.  Simplify and try to generate more basic structures.  Try to make those diverse.  Then add more depth.

Change each number one by one dude.  It's either a specific algorithm or a specific constant that's throwing you off.

I got lost at your third paragraph :/ Can you please elaborate on the thing that I should also try adjusting

I just got done playing with his code. I took out the multiple calls to srand (now a single call: srand(iseed);), the do nothing for loop and various other oddities ((2 / 1) ?). It now creates very regular terrains. The generated terrains show a very strong rotational symmetry. Each 1/4 of the image is nearly an exact copy of each other, rotated 90°.

I think the entire algorithm needs to be rewritten.

Sorry yeah the (2/1) thing gets the numbers into the range of -1 and 1. The 1 in that equation is the max number in the set of numbers. And what algorithm needs to be rewritten, the island masking one? :/ Because if that is so, I have no clue what to do. I just followed what this guy said he did on his blog.

The algorithm used looks like the same from: http://breinygames.blogspot.nl/2012/06/generating-terrain-using-perlin-noise.html

Just playing around a little (I did change some code so I could more easily read it), here is what I came up with:

//Little program to generate test map with only 0 and 1 tile

#include <iostream>
#include <noise/noise.h>
#include "noiseutils.h"
#include <stdlib.h>
#include <string>
#include <sstream>

using namespace std;
using namespace noise;

template <typename T> string tostring (T v) {
ostringstream ss;
ss << v;
return ss.str();
}

void generate_island(int iseed) {
module::Perlin myModule;

myModule.SetSeed (iseed);
utils::NoiseMap heightMap;
utils::NoiseMapBuilderPlane heightMapBuilder;
heightMapBuilder.SetSourceModule(myModule);
heightMapBuilder.SetDestNoiseMap(heightMap);
heightMapBuilder.SetDestSize(512, 512);
heightMapBuilder.SetBounds(2.0, 6.0, 1.0, 5.0);
heightMapBuilder.Build();

float islandMap[512][512];
srand(iseed);

for (int count = 0; count < 1; count++ ){
//Initialize values for a new map
for (int i = 0; i < 512; i++) {
for (int j = 0; j < 512; j++) {
islandMap[j][i] = 0;
}
}

//Choose a random location, travel in random directions
int x = 0, y = 0;
float previous = 0;

for (int i = 0; i < 1000000; i++) {
if(y == 511 || y == 0 || x == 511 || x == 0) {
x = rand() % 512;
y = rand() % 512;
}

if(previous >= islandMap[x][y]) {
islandMap[x][y] += 1;
}

previous = islandMap[x][y];

switch(rand() % 4) {
case 0:
x -= 1;
break;
case 1:
y -= 1;
break;
case 2:
x += 1;
break;
case 3:
y += 1;
break;
default:
break;
}
}

//find max value for normalizing
for (int i = 0; i < 512; i++) {
for (int j = 0; j < 512; j++) {
islandMap[i][j] = islandMap[i][j] * 2 - 1;
}
}

int max = 0;
int min = 0;
for (int i = 0; i < 512; i++) {
for (int j = 0; j < 512; j++) {
if(max < islandMap[i][j]) {
max = islandMap[i][j];
}

if(min > islandMap[i][j]) {
min = islandMap[i][j];
}
}
}

//Multiply values of original by new maps generated
for (int i = 0; i < 512; i++) {
for (int j = 0; j < 512; j++) {
float islandValue = (islandMap[i][j] - min) / (max - min);
float mapValue = (heightMap.GetValue(i, j) + 1) / 2;
float newValue = 2 * islandValue * mapValue - 1;
heightMap.SetValue(i, j, newValue);
}
}
}

utils::RendererImage renderer;
utils::Image image;
renderer.SetSourceNoiseMap (heightMap);
renderer.SetDestImage (image);
renderer.EnableLight ();
renderer.SetLightContrast (3.0);
renderer.SetLightBrightness (2.0);
renderer.Render ();

utils::WriterBMP writer;
writer.SetSourceImage (image);
writer.SetDestFilename ("tutorial" + tostring(iseed) + ".bmp");
writer.WriteDestFile ();
}

int main() {
for(int i=0; i<10; ++i){
generate_island(i);
}
return 0;
}


Thankyou very much for this! I like the randomness and I love the code but do you know if there is any way to make it less "holey". There are specks of water all over the terrain and what I am going for is more of a solid island surrounded by water

### #1Riztro

Posted 27 December 2012 - 07:49 PM

Your seed is always the same... Always 57/17.
-What is the reason behind it, I wonder?

You're calling srand all time. -You should only be calling it once (it keeps the following numbers the same for every time it's invoked with the same seed. The behaviours you're experiencing is familiar to when i did it years ago.
To elaborate on SuperVGA, this line is the line that is fishy:

srand((iseed*57)/(iseed*17));

The iseed in the numerator is cancelled by the iseed in the denominator, causing the seed to always be 57/17, or 3, when the island mask is generated.

Thankyou for pointing that out! I have fixed that but now I am still getting similar maps.. :/. I am sure changing that helps though

I'd rebuild it, piece by piece.  That's obviously terrible advice, but its honestly what I would do.

Although I didn't look at your code, you might try this:
You might want to generate a constant perlin noise and a random location, instead of a random perlin noise and a constant location.

Also try adjusting the map maximums to some number which is coprime to the number you're using right now.  Avoid Mersenne numbers.  If that doesn't work, try again with a number coprime to both of those.  You might be generating a specific repeating pattern or something.  Well, no, the map would be offset I suppose.

Not sure.  Simplify and try to generate more basic structures.  Try to make those diverse.  Then add more depth.

Change each number one by one dude.  It's either a specific algorithm or a specific constant that's throwing you off.

I got lost at your third paragraph :/ Can you please elaborate on the thing that I should also try adjusting

I just got done playing with his code. I took out the multiple calls to srand (now a single call: srand(iseed);), the do nothing for loop and various other oddities ((2 / 1) ?). It now creates very regular terrains. The generated terrains show a very strong rotational symmetry. Each 1/4 of the image is nearly an exact copy of each other, rotated 90°.

I think the entire algorithm needs to be rewritten.

Sorry yeah the (2/1) thing gets the numbers into the range of -1 and 1. The 1 in that equation is the max number in the set of numbers. And what algorithm needs to be rewritten, the island masking one? :/ Because if that is so, I have no clue what to do. I just followed what this guy said he did on his blog

PARTNERS