SimplexNoise.h

#pragma once
#ifndef SIMPLEX_NOISE_H
#define SIMPLEX_NOISE_H

// Implementation of Simplex Noise (in 2D)
//
// Adapts/ports some of Stefan Gustavson's Java code from his 2005 paper "Simplex noise demystified"
//
// Simplex Noise in 3D or higher is protected by patent, and implementations of 2D Simplex Noise are often
// protected by licenses that place too much restriction on usage. Open Simplex is a very good alternative,
// but I feel it's overkill if you only desire to utilize 2D noise. As such, I thought a lightweight
// implementation of the 2D function was warranted.
//
// My _code_ is offered under the MIT license, but there may be restrictions I'm unaware of governing use
// of the algorithm itself, or the use of Gustavson's adaption of it. Please be wary of that.

double SimplexNoise2D(int xin, int yin);

#endif

SimplexNoise.cpp

#include "SimplexNoise.h"
#include <math.h>

// Gradients for use in noise generation. coincicde with mid-points of sides of a unit cube
// Exact array proposed by Gustavson
int grads[12][3] = {
	{ 1,1,0 },{ -1,1,0 },{ 1,-1,0 },{ -1,-1,0 },
	{ 1,0,1 },{ -1,0,1 },{ 1,0,-1 },{ -1,0,-1 },
	{ 0,1,1 },{ 0,-1,1 },{ 0,1,-1 },{ 0,-1,-1 }
};

// Instead of algorithmically copying the array -- we just repeat it twice
int permutations[512] = {
	151,160,137,91,90,15,
	131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
	190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
	88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
	77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
	102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
	135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
	5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
	223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
	129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
	251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
	49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
	138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180,

	151,160,137,91,90,15,
	131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
	190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
	88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
	77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
	102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
	135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
	5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
	223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
	129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
	251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
	49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
	138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180
};

// Helper function: dot product for 2D-vectors
double dotprod(int *g, double x, double y) { return g[0]*x + g[1]*y; }

// Implementation of noise function in 2D
double SimplexNoise2D(int xin, int yin) {

	// Determine which simplex cell we're in
	// Changes here include simplifying some constants and expressions, and trusting the
        // C standard library implementation of floor()
	double F2 = 0.36602540378; // Simplification of: 0.5* (sqrt(3.0) - 1.0);
	double s = (xin + yin) * F2; 
	int i = floor(xin + s);
	int j = floor(yin + s);
	double G2 = 0.2113248654; // Simplification of: (3.0 - sqrt(3.0)) / 6.0;
	double t = (i + j) * G2;
	double x0 = xin - (i - t);
	double y0 = yin - (j - t);

	// Determine which simplex we're in
	// Refactored a little to take advantage of the fact that true or false equals 1 or 0
	double x1 = x0 - (x0 > y0) + G2;
	double x2 = x0 - 1.0 + 2.0 * G2;
	double y1 = y0 - (x0 <= y0) + G2;
	double y2 = y0 - 1.0 + 2.0 * G2;

	// Get the hashed gradient indices, using same x0 and y0 values as above to slightly refactor
	int ii = i & 255;
	int jj = j & 255;
	int gradient0 = permutations[ii + permutations[jj]] % 12;
	int gradient1 = permutations[ii + (x0 > y0) + permutations[jj + (x0 <= y0)]] % 12;
	int gradient2 = permutations[ii + 1 + permutations[jj + 1]] % 12;

	// We use one variable for summing the noise. This allows us to remove some else statements
	// and heavily refactor the code here,
	double noiseSum = 0;
	double t0 = 0.5 - x0*x0 - y0*y0;
	double t1 = 0.5 - x1*x1 - y1*y1;
	double t2 = 0.5 - x2*x2 - y2*y2;
	if (t0 >= 0) { noiseSum += t0 * t0 * t0 *t0 * dotprod(grads[gradient0], x0, y0);  }
	if (t1 >= 0) { noiseSum += t1 * t1 * t1 * t1 * dotprod(grads[gradient1], x1, y1);}
	if (t2 >= 0) { noiseSum += t2 * t2 * t2 * t2 * dotprod(grads[gradient2], x2, y2); }

	// Add contributions from each corner to get the final noise value
	return (70.0 * noiseSum);
}