using UnityEngine;
namespace StixGames.NatureCore.Utility
{
public class Sampler2D
{
public readonly ISampler X, Y;
public Sampler2D(ISampler x, ISampler y)
{
X = x;
Y = y;
}
///
/// Generates a vector with x and y between 0 and 1
///
///
public Vector2 NextVector2D()
{
return new Vector2(X.NextFloat(), Y.NextFloat());
}
public void Skip(int amount = 1)
{
X.Skip(amount);
Y.Skip(amount);
}
public void Reset()
{
X.Reset();
Y.Reset();
}
}
public class HaltonSampler : ISampler
{
public readonly int Base;
public readonly int StartIndex;
private int index;
public HaltonSampler(int @base, int startIndex)
{
Base = @base;
StartIndex = startIndex;
index = StartIndex;
}
public float NextFloat()
{
int i = index;
double f = 1;
double r = 0;
while (i > 0)
{
f = f / Base;
r = r + f * (i % Base);
i = i / Base;
}
index++;
return (float) r;
}
public void Skip(int amount = 1)
{
index += amount;
}
public void Reset()
{
index = StartIndex;
}
}
public class RandomSampler : ISampler
{
public readonly int Seed;
private System.Random rng;
public RandomSampler(int seed)
{
Seed = seed;
rng = new System.Random(seed);
}
public float NextFloat()
{
return rng.NextFloat();
}
public void Skip(int amount = 1)
{
for (int i = 0; i < amount; i++)
{
rng.NextFloat();
}
}
public void Reset()
{
rng = new System.Random(Seed);
}
}
public interface ISampler
{
///
/// Generate a float between 0 and 1
///
///
float NextFloat();
///
/// Skip one value
///
///
void Skip(int amount = 1);
///
/// Reset to the start seed
///
void Reset();
}
public static class SamplerExtensions
{
public static float Range(this ISampler sampler, float start, float end)
{
return sampler.NextFloat() * (end - start) + start;
}
public static int Range(this ISampler sampler, int start, int end)
{
return (int)(sampler.NextFloat() * (end - start) + start);
}
}
}