# SiNoise Part2

Read the first part here

So now I've come to the implementing the actual thing. And yes I have a name for it, which should be apparent by now- SiNoise.

I'll be explaining the simplex approach here, perlin is pretty simple compared to that and I'll leave a link to the code.

The full code for Simplex approach is here and Perlin approach is here.

For brevity, here's the relevant function-

```
public float noiseWrapper(int x, int y, float xCenter, float yCenter, float minDistance, float maxDistance) {
Vector2f relative = new Vector2f((float) x - xCenter, (float) y - yCenter);
if (relative.equals(Vector2f.zero())) {
return 1.0f;
}
float scaledAngle = (((float) Math.atan2(relative.y, relative.x) + (float) Math.PI) * ((float) gridSize * simplexMagicNumber)) / (2.0f * (float) Math.PI);
float b = 1.0f / minDistance;
float a = 1.0f / maxDistance - b;
float adjustedNoise = (a * ((tileableNoise.noise(scaledAngle, scaledAngle) + 1.0f) / 2.0f) + b) * relative.length();
return 1.0f - TeraMath.clamp(adjustedNoise);
}
```

`x`

,`y`

being the coordinates for which noise in required, `xCenter`

,`yCenter`

being the geometric centre of the area reserved. and `minDistance`

,`maxDistance`

being the minimum and maximum distance a peripheral point can have from the centre.

Walkthrough time

```
return 1.0f - TeraMath.clamp(adjustedNoise);
```

Wait... this is the last line. But yeah the thing is notice here that noise values are being flipped over here i.e. before this `adjustedNoise = 1`

on peripheri and `adjustedNoise = 0`

at centre. This makes things easier to comprehend as you'll see later.

```
Vector2f relative = new Vector2f((float) x - xCenter, (float) y - yCenter);
```

Save the coordinates in a vector, so I can spare calculating the distance by hand.

```
if (relative.equals(Vector2f.zero())) {
return 1.0f;
}
```

This is a corner case as we can't really have an angle defined for the centre and the noise value of `1.0`

signifies that this is the centre.

```
float scaledAngle = (((float) Math.atan2(relative.y, relative.x) + (float) Math.PI) * ((float) gridSize * simplexMagicNumber)) / (2.0f * (float) Math.PI);
```

`((float) Math.atan2(relative.y, relative.x) + (float) Math.PI)`

gets the angle for the point and shift it from [-π,π] to [0, 2π]. `/ (2.0f * (float) Math.PI)`

map to [0,1]. `* ((float) gridSize * simplexMagicNumber)`

map to [0, edgeOfDiagonal](hint: read last post).

```
float b = 1.0f / minDistance;
float a = 1.0f / maxDistance - b;
```

This is to impose the new constraints of `minDistance`

and `maxDistance`

. The idea of `maxDistance`

was introduced in the last post but now there's `minDistance`

as well, so, consider this-
`f(θ, distance) = (a * Noise(θ) + b) * distance`

`Noise(θ) ∈ [0,1]`

, so lets have a look at the extreme conditions and apply the constraints there.
When `Noise(θ) == 0`

, `f == 1`

for `distance == minDistance`

Similarly,
When `Noise(θ) == 1`

, `f == 1`

for `distance == maxDistance`

2 equations, 2 variables, solve it and you'll get the values I got.

```
float adjustedNoise = (a * ((tileableNoise.noise(scaledAngle, scaledAngle) + 1.0f) / 2.0f) + b) * relative.length();
```

¯\_(ツ)_/¯

Now to show you some results-

Perlin with `gridSize = 4`

, `minDistance = 20`

, `maxDistance = 50`

Perlin with `gridSize = 20`

, rest same

Now you dhould be able to appreciate the control over `gridSize`

:)

Next up... Volcano!!!

#procgen #proceduralgeneration #noise #perlin #simplex #volcano

- 1 toast