See what's going on with flipcode!




This section of the archives stores flipcode's complete Developer Toolbox collection, featuring a variety of mini-articles and source code contributions from our readers.

 

  Noise Generation Class
  Submitted by



This is the class I ended up with after trying to create a noise function capable of producing noise in any number of dimensions. The constructor is templated to allow a programmer to specify his own random function.

Like the simple:
noise<2 noise2d(rand); 

Or the more useful:
class seeded_random
{
public:
    seeded_random(int seed) { srand(seed); }
    int operator()() { return rand(); }
};

noise<2 noise2d(seeded_random(some_seed));

And so on. The rest of the description is in the file it's self. - Chris Stephenson

Download Associated File: noise.h (3,254 bytes)

//////////////////////////////////////////////////////////////////////////////
//     File: noise.h
//  Created: 18 December 2001
//   Author: Chris Stephenson
//    Email: chris@icezip.com
//  Summary: A class for generating N dimensional noise
//           The noise generated has the following charcteristics:
//             - noise produced between -1 and +1
//             - pseudo-random (same value produced by same vector)
//             - features roughly the same size (no high or low spatial frequencies)
//////////////////////////////////////////////////////////////////////////////

#ifndef __NOISE_H__
#define __NOISE_H__

#include <math.h>

#define cubic_spline(t) (t * t * (3.0f - 2.0f * t)) #define linear_interpolation(t, a, b) (a + t * (b - a))

template<int N> // N must be > 0 class noise { public: // construct the class using the random function/class specified template<class R> noise(R random) { int i,j,k;

for(i = 0; i < buffer_size; i++) { // pointers pointers[i] = i;

// gradients for(j = 0; j < N; j++) gradients[i][j] = (float)((random() % (buffer_size + buffer_size)) - buffer_size) / buffer_size;

// normalize gradients float s = 0.0f;

for(j = 0; j < N; j++) s += gradients[i][j] * gradients[i][j];

s = 1.0f / sqrtf(s);

for(j = 0; j < N; j++) gradients[i][j] *= s; }

// randomize pointers while (--i) { k = pointers[i]; pointers[i] = pointers[j = (random() & buffer_mask)]; pointers[j] = k; }

// copy pointers & gradients to 2nd half of array for(i = 0; i < buffer_size + buffer_pad; i++) { pointers[buffer_size + i] = pointers[i];

for(j = 0; j < N; j++) gradients[buffer_size + i][j] = gradients[i][j];

} }

// get some noise based on vector vec float get(float vec[N]) { int ivec[N]; int p[N]; // pointer offsets float r[N]; // r + ivec = vec (to be dotted with the gradients) float s[N]; // interpolation values // set up all the varables for(int i = 0; i < N; i++) { ivec[i] = floorf(vec[i]); p[i] = ivec[i] & buffer_mask; r[i] = vec[i] - ivec[i]; s[i] = cubic_spline(r[i]); }

// call helper function return _get(p, r, s, 0, 0); }

private: // recursive helper function for get(float vec[N]) inline float _get(int p[N], float r[N], float s[N], int cumulative_p, int n) { if(n == N) // base case: return r dot gradient { float *g = gradients[cumulative_p]; float val = 0.0f; for(int i = 0; i < N; i++) val += r[i] * g[i]; return val; } else // recursive case: return interpolation of values { float a, b;

a = _get(p, r, s, pointers[cumulative_p + p[n]], n + 1);

r[n]-=1.0f; b = _get(p, r, s, pointers[cumulative_p + p[n] + 1], n + 1); r[n]+=1.0f;

return linear_interpolation(s[n], a, b); } }

enum // some private constants { buffer_size = 0x100, // buffer size, must be a power of 2 for mask to work buffer_mask = 0xff, // ANDing (&) is much faster than MODing (%) buffer_pad = 2 // a little extra space for simplification of methods };

// important variables int pointers[buffer_size + buffer_size + buffer_pad]; float gradients[buffer_size + buffer_size + buffer_pad][N]; };

#endif // __NOISE_H__

The zip file viewer built into the Developer Toolbox made use of the zlib library, as well as the zlibdll source additions.

 

Copyright 1999-2008 (C) FLIPCODE.COM and/or the original content author(s). All rights reserved.
Please read our Terms, Conditions, and Privacy information.