# Java Perlin Noise 1D terrain generation problem

• September 12th, 2013, 09:12 AM
Bingo90
Java Perlin Noise 1D terrain generation problem
I'm using 1D Perlin noise to generate a tile-based world. But the hills that generate are too small. I tried changing the values of the parameters of the PerlinNoise1D method (see below), but that not only changed the maximum height, it also changed the gradient, which I was trying to avoid.

(Sorry for the attached images "Insert Image" didn't work)

This is how it generates now:

<Attached as TerrainNow.jpg>

This is how I want it (of course it's not possible to get it that smooth with tiles this is just a sketch):

<Attached as HowIWantIt.jpg>

This is how it looks like when I try to do it myself:

<Attached as Terrain.jpg>

And here's the code I'm using.

Generation Code:

Code :

Tile[][] tiles = new Tile[][];

int offset = 2048;

for(int i = 0;i<tiles[0].length;i++)
{
int y = (int)ClassNoise.PerlinNoise1D(i, 0.5f, 8)*4;
for(int j = offset+y;j<tiles.length;j++)
{
tiles[i,j] = new Tile(i,j);
}
}

ClassNoise class:

Code :

public class ClassNoise
{
public static List<Integer[]> primes = new ArrayList<Integer[]>();

static
{

int prime1 = 0;
int prime2 = 0;
int prime3 = 0;
for (int i = 1; i < 10000000; i+=2)
{

if (isPrime(i))
{
prime1 = i;
for (; i < 10000000; i+=2)
{
if (isPrime(i))
{
prime2 = i;
for (; i < 10000000; i+=2)
{
if (isPrime(i))
{
prime3 = i;

}
}
}
}
}
}
}

public static float Noise(int x, int octave)
{

x = (x << 13) ^ x;
return (float) (1.0 - ((x
* (x * x * primes.get(octave)[0] + primes.get(octave)[1]) + primes.get(octave)[2]) & Integer.MAX_VALUE) / 1073741824f);
}

public static float PerlinNoise1D(float x, float persistence, int octaves)
{
float total = 0;
float p = persistence;
int n = octaves - 1;

float[] octavePostMutliply = { 1, 1, 1, 1, 1, 1, 1, 1 };

for (int i = 0; i <= n; i++)
{

float frequency = (float) Math.pow(2, i);
double amplitude = Math.pow(p, octaves - i);
total += InterpolatedNoise(x * frequency, i) * amplitude
* octavePostMutliply[i];
}

}

private static float InterpolatedNoise(float x, int octave)
{
int integer_X = (int) x;
float fractional_X = x - integer_X;

float v1 = SmoothNoise1D(integer_X, octave);
float v2 = SmoothNoise1D(integer_X + 1, octave);

return CosineInterpolate(v1, v2, fractional_X);

}

public static float CosineInterpolate(float a, float b, float x)
{
float ft = (float) (x * Math.PI);
float f = (float) ((1 - Math.cos(ft)) * 0.5);

return a * (1 - f) + b * f;
}

public static float SmoothNoise1D(int x, int octave)
{
return Noise(x, octave) / 2 + Noise(x - 1, octave) / 4 + Noise(x + 1, octave) / 4;
}

private static boolean isPrime(int n)
{
if (n % 2 == 0)
return false;
for (int i = 3; i * i <= n; i += 2)
{
if (n % i == 0)
return false;
}
return true;
}

}

• September 12th, 2013, 09:38 AM
KevinWorkman
Re: Java Perlin Noise 1D terrain generation problem
If you change the difference in height, you're going to change the gradient. You have to adjust your x-scale as well to smooth the gradient out a bit.
• September 12th, 2013, 09:52 AM
Bingo90
Re: Java Perlin Noise 1D terrain generation problem
Okay what should I change to do this?
• September 12th, 2013, 10:02 AM
KevinWorkman
Re: Java Perlin Noise 1D terrain generation problem
You have to think about your problem a little more. You haven't posted an SSCCE including the logic that takes these numbers and uses them as drawing coordinates, so it's rather hard to be more specific. The general idea is that if you want to smooth out the gradient but keep the peak heights, you have to stretch out the x axis. How you do that is up to you. Drawing out a few examples on paper might help you.
• September 12th, 2013, 10:09 AM
Bingo90
Re: Java Perlin Noise 1D terrain generation problem
I can't simply scale it because the tiles are stored in an array. I want to change the generation code to generate better hills and drawing shouldn't change.
• September 12th, 2013, 10:12 AM
KevinWorkman
Re: Java Perlin Noise 1D terrain generation problem
When I say scale, I mean you need to scale the data, not the image. The idea is the same though. You're going to have to write some code that takes the noise as input and outputs an array with whatever smoothing you want.
• September 12th, 2013, 10:23 AM
Bingo90
Re: Java Perlin Noise 1D terrain generation problem
When scaling it it would double the x-size of the "hills" but the gradient would still be too rough.
• September 12th, 2013, 10:55 AM
KevinWorkman
Re: Java Perlin Noise 1D terrain generation problem
That's why you also have to fill in the blanks. Say your noise creates this:

**
**
** **
**********

You'd have to fill in the blanks to create something more like this:

**
****
** ******
**********

--- Update ---

Ugh, the edit button is broken and that didn't work out how I wanted, but what I mean is you can't just stretch your x axis. You also have to fill in the blanks to create a smoother surface.
• September 12th, 2013, 12:45 PM
Bingo90
Re: Java Perlin Noise 1D terrain generation problem
So it's absoloutely impossible to change the maximum height without changing the gradient?

--- Update ---

Okay what changes should I make to my code that is works like I want? How do I check if the blank is a blank that should be filled?
• September 12th, 2013, 12:59 PM
KevinWorkman
Re: Java Perlin Noise 1D terrain generation problem
There isn't any particular single exact correct way to accomplish your goal, which is why it's difficult to help you with the questions you're asking. We can't give you code like you're asking for. You're going to have to play around and try stuff on your own. I've given you the basics of the approach I would take, but it's up to you to come up with the algorithm based on your exact needs. Try something out and post an updated SSCCE when you get stuck again, and we'll go from there.