public new float GetValue(float x, float y)
{
// Noise contributions from the three corners
float n0 = 0, n1 = 0, n2 = 0;
// Skew the input space to determine which simplex cell we're in
float s = (x + y)*F2; // Hairy factor for 2D
int i = Libnoise.FastFloor(x + s);
int j = Libnoise.FastFloor(y + s);
float t = (i + j)*G2;
// The x,y distances from the cell origin
float x0 = x - (i - t);
float y0 = y - (j - t);
// For the 2D case, the simplex shape is an equilateral triangle.
// Determine which simplex we are in.
// Offsets for second (middle) corner of simplex in (i,j)
int i1, j1;
if (x0 > y0)
{
// lower triangle, XY order: (0,0)->(1,0)->(1,1)
i1 = 1;
j1 = 0;
}
else
{
// upper triangle, YX order: (0,0)->(0,1)->(1,1)
i1 = 0;
j1 = 1;
}
// A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and
// a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where
// c = (3-sqrt(3))/6
float x1 = x0 - i1 + G2; // Offsets for middle corner in (x,y) unskewed
float y1 = y0 - j1 + G2;
float x2 = x0 + G22; // Offsets for last corner in (x,y) unskewed
float y2 = y0 + G22;
// Work out the hashed gradient indices of the three simplex corners
int ii = i & 0xff;
int jj = j & 0xff;
// Calculate the contribution from the three corners
float t0 = 0.5f - x0*x0 - y0*y0;
if (t0 > 0)
{
t0 *= t0;
int gi0 = Random[ii + Random[jj]]%12;
n0 = t0*t0*Dot(Grad3[gi0], x0, y0); // (x,y) of grad3 used for
// 2D gradient
}
float t1 = 0.5f - x1*x1 - y1*y1;
if (t1 > 0)
{
t1 *= t1;
int gi1 = Random[ii + i1 + Random[jj + j1]]%12;
n1 = t1*t1*Dot(Grad3[gi1], x1, y1);
}
float t2 = 0.5f - x2*x2 - y2*y2;
if (t2 > 0)
{
t2 *= t2;
int gi2 = Random[ii + 1 + Random[jj + 1]]%12;
n2 = t2*t2*Dot(Grad3[gi2], x2, y2);
}
// Add contributions from each corner to get the final noise value.
// The result is scaled to return values in the interval [-1,1].
return 70.0f*(n0 + n1 + n2);
}