city-generation/Game/Assets/Scripts/Noise/NoiseGenerator.cs

138 lines
4.7 KiB
C#
Raw Normal View History

2015-05-08 10:20:13 +00:00
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using TransportGame.Utils;
namespace TransportGame.Noise
{
public abstract class NoiseGenerator
{
public float Scale { get; set; }
public float Low { get; set; }
public float High { get; set; }
public float NonLinearPower { get; set; }
public int Octaves { get; set; }
public float Persistence { get; set; }
private float seedX, seedY;
public NoiseGenerator()
{
System.Random random = new System.Random();
seedX = random.NextSingle(-10000f, 10000f);
seedY = random.NextSingle(-10000f, 10000f);
Scale = 1f;
Low = -1f;
High = 1f;
NonLinearPower = 1f;
Octaves = 1;
Persistence = .5f;
}
/// <summary>
/// Produces noise in the [-1,1] interval
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
protected abstract float GenerateNoise(float x, float y);
/// <summary>
/// Generates noise
/// </summary>
/// <param name="x">X coordinate</param>
/// <param name="y">Y coordinate</param>
/// <param name="low">Minimum value</param>
/// <param name="high">Maximum value</param>
/// <param name="scale">Scale</param>
/// <param name="octaves">Number of octaves (layers)</param>
/// <param name="persistence">Persistence (impact of each layer)</param>
/// <param name="nonLinearPower">Non-linearity</param>
/// <returns>Noise</returns>
public float Generate(float x, float y, float low, float high, float scale, int octaves, float persistence, float nonLinearPower)
{
float value = 0;
int freq = 1;
float amp = 1;
float maxAmp = 0;
for (int i = 0; i < octaves; ++i)
{
value += GenerateNoise(seedX + freq * scale * x, seedY + freq * scale * y) * amp;
maxAmp += amp;
amp *= persistence;
freq *= 2;
}
// Bring to [0,1]
value = (value / maxAmp) / 2f + .5f;
// Raise to non-linear power
value = Mathf.Pow(value, nonLinearPower);
// Bring to required interval
value = value * (high - low) + low;
// Done
return value;
}
/// <summary>
/// Generates noise
/// </summary>
/// <param name="x">X coordinate</param>
/// <param name="y">Y coordinate</param>
/// <param name="low">Minimum value</param>
/// <param name="high">Maximum value</param>
/// <param name="scale">Scale</param>
/// <param name="octaves">Number of octaves (layers)</param>
/// <param name="persistence">Persistence (impact of each layer)</param>
/// <returns>Noise</returns>
public float Generate(float x, float y, float low, float high, float scale, int octaves, float persistence)
{
return Generate(x, y, low, high, scale, octaves, persistence, NonLinearPower);
}
/// <summary>
/// Generates noise
/// </summary>
/// <param name="x">X coordinate</param>
/// <param name="y">Y coordinate</param>
/// <param name="low">Minimum value</param>
/// <param name="high">Maximum value</param>
/// <param name="scale">Scale</param>
/// <returns>Noise</returns>
public float Generate(float x, float y, float low, float high, float scale)
{
return Generate(x, y, low, high, scale, Octaves, Persistence, NonLinearPower);
}
/// <summary>
/// Generates noise
/// </summary>
/// <param name="x">X coordinate</param>
/// <param name="y">Y coordinate</param>
/// <param name="low">Minimum value</param>
/// <param name="high">Maximum value</param>
/// <returns>Noise</returns>
public float Generate(float x, float y, float low, float high)
{
return Generate(x, y, low, high, Scale, Octaves, Persistence, NonLinearPower);
}
/// <summary>
/// Generates noise
/// </summary>
/// <param name="x">X coordinate</param>
/// <param name="y">Y coordinate</param>
/// <returns>Noise</returns>
public float Generate(float x, float y)
{
return Generate(x, y, Low, High, Scale, Octaves, Persistence, NonLinearPower);
}
}
}