#/************************************************************************ #* * #* Copyright (C) 2002 3Dlabs Inc. Ltd. * #* * #************************************************************************/ from math import * from Numeric import * #/* Coherent noise function over 1, 2 or 3 dimensions */ #/* (copyright Ken Perlin) */ MAXB = 0x100 N = 0x1000 NP = 12 #/* 2^N */ NM = 0xfff start = 1 B = 1 BM = 0 p = zeroes(MAXB + MAXB + 2) g3 = zeroes(MAXB + MAXB + 2,3) g2 = zeroes(MAXB + MAXB + 2,2) g1 = zeroes(MAXB + MAXB + 2,1) def s_curve(t): return ( t * t * (3. - 2. * t) ) def lerp(t, a, b): return ( a + t * (b - a) ) def setup(i,b0,b1,r0,r1): t = vec[i] + N\ b0 = ((int)t) & BM\ b1 = (b0+1) & BM\ r0 = t - (int)t\ r1 = r0 - 1. def at2(rx,ry): return ( rx * q[0] + ry * q[1] ) def at3(rx,ry,rz): return ( rx * q[0] + ry * q[1] + rz * q[2] ) initNoise(void) def SetNoiseFrequency(frequency): start = 1 B = frequency BM = B-1 def noise1(arg): { bx0, bx1 double rx0, rx1, sx, t, u, v, vec[1] vec[0] = arg if (start): start = 0 initNoise() setup(0,bx0,bx1,rx0,rx1) sx = s_curve(rx0) u = rx0 * g1[ p[ bx0 ] ] v = rx1 * g1[ p[ bx1 ] ] return(lerp(sx, u, v)) } double noise2(double vec[2]) { bx0, bx1, by0, by1, b00, b10, b01, b11 double rx0, rx1, ry0, ry1, *q, sx, sy, a, b, t, u, v i, j if (start) { start = 0 initNoise() } setup(0, bx0,bx1, rx0,rx1) setup(1, by0,by1, ry0,ry1) i = p[ bx0 ] j = p[ bx1 ] b00 = p[ i + by0 ] b10 = p[ j + by0 ] b01 = p[ i + by1 ] b11 = p[ j + by1 ] sx = s_curve(rx0) sy = s_curve(ry0) q = g2[ b00 ] u = at2(rx0,ry0) q = g2[ b10 ] v = at2(rx1,ry0) a = lerp(sx, u, v) q = g2[ b01 ] u = at2(rx0,ry1) q = g2[ b11 ] v = at2(rx1,ry1) b = lerp(sx, u, v) return lerp(sy, a, b) } double noise3(double vec[3]) { bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11 double rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v i, j if (start) { start = 0 initNoise() } setup(0, bx0,bx1, rx0,rx1) setup(1, by0,by1, ry0,ry1) setup(2, bz0,bz1, rz0,rz1) i = p[ bx0 ] j = p[ bx1 ] b00 = p[ i + by0 ] b10 = p[ j + by0 ] b01 = p[ i + by1 ] b11 = p[ j + by1 ] t = s_curve(rx0) sy = s_curve(ry0) sz = s_curve(rz0) q = g3[ b00 + bz0 ] u = at3(rx0,ry0,rz0) q = g3[ b10 + bz0 ] v = at3(rx1,ry0,rz0) a = lerp(t, u, v) q = g3[ b01 + bz0 ] u = at3(rx0,ry1,rz0) q = g3[ b11 + bz0 ] v = at3(rx1,ry1,rz0) b = lerp(t, u, v) c = lerp(sy, a, b) q = g3[ b00 + bz1 ] u = at3(rx0,ry0,rz1) q = g3[ b10 + bz1 ] v = at3(rx1,ry0,rz1) a = lerp(t, u, v) q = g3[ b01 + bz1 ] u = at3(rx0,ry1,rz1) q = g3[ b11 + bz1 ] v = at3(rx1,ry1,rz1) b = lerp(t, u, v) d = lerp(sy, a, b) //fprintf(stderr, "%f\n", lerp(sz, c, d)) return lerp(sz, c, d) } normalize2(double v[2]) { double s s = sqrt(v[0] * v[0] + v[1] * v[1]) v[0] = v[0] / s v[1] = v[1] / s } normalize3(double v[3]) { double s s = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]) v[0] = v[0] / s v[1] = v[1] / s v[2] = v[2] / s } initNoise(void) { i, j, k srand(30757) for (i = 0 i < B i++) { p[i] = i g1[i] = (double)((rand() % (B + B)) - B) / B for (j = 0 j < 2 j++) g2[i][j] = (double)((rand() % (B + B)) - B) / B normalize2(g2[i]) for (j = 0 j < 3 j++) g3[i][j] = (double)((rand() % (B + B)) - B) / B normalize3(g3[i]) } while (--i) { k = p[i] p[i] = p[j = rand() % B] p[j] = k } for (i = 0 i < B + 2 i++) { p[B + i] = p[i] g1[B + i] = g1[i] for (j = 0 j < 2 j++) g2[B + i][j] = g2[i][j] for (j = 0 j < 3 j++) g3[B + i][j] = g3[i][j] } } /* --- My harmonic summing functions - PDB --------------------------*/ /* In what follows "alpha" is the weight when the sum is formed. Typically it is 2, As this approaches 1 the function is noisier. "beta" is the harmonic scaling/spacing, typically 2. */ double PerlinNoise1D(double x,double alpha,double beta,n) { i double val,sum = 0 double p,scale = 1 p = x for (i=0i