// Compute Perlin noise at coordinates x, y float Perlin::getPerlin(float x, float y) { // Determine grid cell coordinates int x0 = (x >= 0.0 ? (int)x : (int)x - 1); int x1 = x0 + 1; int y0 = (y >= 0.0 ? (int)y : (int)y - 1); int y1 = y0 + 1; // Determine interpolation weights float sx = x - (float)x0; float sy = y - (float)y0; // Interpolate between grid point gradients float n0, n1, ix0, ix1, value; n0 = dotGridGradient(x0, y0, x, y); n1 = dotGridGradient(x1, y0, x, y); ix0 = lerp(n0, n1, sx); n0 = dotGridGradient(x0, y1, x, y); n1 = dotGridGradient(x1, y1, x, y); ix1 = lerp(n0, n1, sx); value = lerp(ix0, ix1, sy); float ret = value; return ret; }
// https://en.wikipedia.org/wiki/Perlin_noise // here the input floats are fractions we must find the closest sample for float Terrain::getHeight(float x, float y) { // Determine grid cell coordinates // send to full grid float unfloored_x = (x * (bounds.xmax - bounds.xmin)) + (bounds.xmin); float unfloored_y = (y * (bounds.ymax - bounds.ymin)) + (bounds.ymin); int x0 = clamp(floor(unfloored_x), bounds.xmin, bounds.xmax - 1); int y0 = clamp(floor(unfloored_y), bounds.ymin, bounds.ymax - 1); int x1 = clamp(floor(x0 + 1), bounds.xmin, bounds.xmax - 1); int y1 = clamp(floor(y0 + 1), bounds.ymin, bounds.ymax - 1); float sx = unfloored_x - (float) x0; float sy = unfloored_y - (float) y0; float n0, n1, ix0, ix1, value; n0 = dotGridGradient(x0, y0, x, y); n1 = dotGridGradient(x1, y0, x, y); ix0 = lerp(n0, n1, sx); n0 = dotGridGradient(x0, y1, x, y); n1 = dotGridGradient(x1, y1, x, y); ix1 = lerp(n0, n1, sx); value = lerp(ix0, ix1, sy); return value; }