Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

perlin.cpp

Go to the documentation of this file.
00001 #include <stdlib.h>
00002 #include <stdio.h>
00003 #include <math.h>
00004 
00005 #include "mathlib.h"
00006 #include "vecmath.h"
00007 #include "perlin.h"
00008 
00009 
00010 float bias(float a, float b)
00011 {
00012     return (float) pow((double) a, log((double) b) / log(0.5));
00013 }
00014 
00015 float gain(float a, float b)
00016 {
00017     float p = (float) (log(1.0 - b) / log(0.5));
00018 
00019     if (a < 0.001f)
00020         return 0.0f;
00021     else if (a > 0.999f)
00022         return 1.0f;
00023 
00024     if (a < 0.5f)
00025         return (float) pow(2 * a, p) / 2;
00026     else
00027         return 1.0f - (float) pow(2.0 * (1.0 - a), (double) p) / 2;
00028 }
00029 
00030 float noise(float vec[], int len)
00031 {
00032     switch (len) {
00033     case 0:
00034         return 0.;
00035     case 1:
00036         return noise1(vec[0]);
00037     case 2:
00038         return noise2(vec);
00039     default:
00040         return noise3(vec);
00041     }
00042 }
00043 
00044 
00045 float turbulence(float v[], float freq)
00046 {
00047     float t, vec[3];
00048 
00049     for (t = 0. ; freq >= 1. ; freq /= 2) {
00050         vec[0] = freq * v[0];
00051         vec[1] = freq * v[1];
00052         vec[2] = freq * v[2];
00053         t += (float) fabs(noise3(vec)) / freq;
00054     }
00055     return t;
00056 }
00057 
00058 
00059 float turbulence(const Point2f& p, float freq)
00060 {
00061     float t;
00062     float vec[2];
00063 
00064     for (t = 0.0f; freq >= 1.0f; freq *= 0.5f)
00065     {
00066         vec[0] = freq * p.x;
00067         vec[1] = freq * p.y;
00068         t += (float) fabs(noise2(vec)) / freq;
00069     }
00070 
00071     return t;
00072 }
00073 
00074 
00075 float turbulence(const Point3f& p, float freq)
00076 {
00077     float t;
00078     float vec[3];
00079 
00080     for (t = 0.0f; freq >= 1.0f; freq *= 0.5f)
00081     {
00082         vec[0] = freq * p.x;
00083         vec[1] = freq * p.y;
00084         vec[2] = freq * p.z;
00085         t += (float) fabs(noise3(vec)) / freq;
00086     }
00087 
00088     return t;
00089 }
00090 
00091 
00092 float fractalsum(float v[], float freq)
00093 {
00094     float t;
00095     float vec[3];
00096 
00097     for (t = 0.0f ; freq >= 1.0f ; freq /= 2.0f) {
00098         vec[0] = freq * v[0];
00099         vec[1] = freq * v[1];
00100         vec[2] = freq * v[2];
00101         t += noise3(vec) / freq;
00102     }
00103 
00104     return t;
00105 }
00106 
00107 
00108 float fractalsum(const Point2f& p, float freq)
00109 {
00110     float t;
00111     float vec[2];
00112 
00113     for (t = 0.0f; freq >= 1.0f; freq *= 0.5f)
00114     {
00115         vec[0] = freq * p.x;
00116         vec[1] = freq * p.y;
00117         t += noise2(vec) / freq;
00118     }
00119 
00120     return t;
00121 }
00122 
00123 
00124 float fractalsum(const Point3f& p, float freq)
00125 {
00126     float t;
00127     float vec[3];
00128 
00129     for (t = 0.0f; freq >= 1.0f; freq *= 0.5f)
00130     {
00131         vec[0] = freq * p.x;
00132         vec[1] = freq * p.y;
00133         vec[2] = freq * p.z;
00134         t += noise3(vec) / freq;
00135     }
00136 
00137     return t;
00138 }
00139 
00140 
00141 /* noise functions over 1, 2, and 3 dimensions */
00142 
00143 #define B 0x100
00144 #define BM 0xff
00145 
00146 #define N 0x1000
00147 #define NP 12   /* 2^N */
00148 #define NM 0xfff
00149 
00150 static int p[B + B + 2];
00151 static float g3[B + B + 2][3];
00152 static float g2[B + B + 2][2];
00153 static float g1[B + B + 2];
00154 
00155 static bool initialized = false;
00156 
00157 static void init(void);
00158 
00159 #define s_curve(t) ( t * t * (3.0f - 2.0f * t) )
00160 
00161 #define setup(i, b0, b1, r0, r1) \
00162         t = vec[i] + N;\
00163         b0 = ((int)t) & BM;\
00164         b1 = (b0+1) & BM;\
00165         r0 = t - (int)t;\
00166         r1 = r0 - 1.0f;
00167 
00168 float noise1(float arg)
00169 {
00170     if (!initialized)
00171         init();
00172 
00173     int bx0, bx1;
00174     float rx0, rx1, t, u, v, vec[1];
00175 
00176     vec[0] = arg;
00177 
00178     setup(0, bx0, bx1, rx0, rx1);
00179 
00180     u = rx0 * g1[p[bx0]];
00181     v = rx1 * g1[p[bx1]];
00182 
00183     return Mathf::lerp(s_curve(rx0), u, v);
00184 }
00185 
00186 float noise2(float vec[2])
00187 {
00188         int bx0, bx1, by0, by1, b00, b10, b01, b11;
00189         float rx0, rx1, ry0, ry1, *q, sx, sy, a, b, t, u, v;
00190         int i, j;
00191 
00192         if (!initialized)
00193             init();
00194 
00195         setup(0, bx0,bx1, rx0,rx1);
00196         setup(1, by0,by1, ry0,ry1);
00197 
00198         i = p[ bx0 ];
00199         j = p[ bx1 ];
00200 
00201         b00 = p[ i + by0 ];
00202         b10 = p[ j + by0 ];
00203         b01 = p[ i + by1 ];
00204         b11 = p[ j + by1 ];
00205 
00206         sx = s_curve(rx0);
00207         sy = s_curve(ry0);
00208 
00209 #define at2(rx,ry) ( rx * q[0] + ry * q[1] )
00210 
00211         q = g2[ b00 ] ; u = at2(rx0,ry0);
00212         q = g2[ b10 ] ; v = at2(rx1,ry0);
00213         a = Mathf::lerp(sx, u, v);
00214 
00215         q = g2[ b01 ] ; u = at2(rx0,ry1);
00216         q = g2[ b11 ] ; v = at2(rx1,ry1);
00217         b = Mathf::lerp(sx, u, v);
00218 
00219         return Mathf::lerp(sy, a, b);
00220 }
00221 
00222 float noise3(float vec[3])
00223 {
00224         if (!initialized)
00225             init();
00226 
00227         int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
00228         float rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v;
00229         int i, j;
00230 
00231         setup(0, bx0,bx1, rx0,rx1);
00232         setup(1, by0,by1, ry0,ry1);
00233         setup(2, bz0,bz1, rz0,rz1);
00234 
00235         i = p[ bx0 ];
00236         j = p[ bx1 ];
00237 
00238         b00 = p[ i + by0 ];
00239         b10 = p[ j + by0 ];
00240         b01 = p[ i + by1 ];
00241         b11 = p[ j + by1 ];
00242 
00243         t  = s_curve(rx0);
00244         sy = s_curve(ry0);
00245         sz = s_curve(rz0);
00246 
00247 #define at3(rx,ry,rz) ( rx * q[0] + ry * q[1] + rz * q[2] )
00248 
00249         q = g3[ b00 + bz0 ] ; u = at3(rx0,ry0,rz0);
00250         q = g3[ b10 + bz0 ] ; v = at3(rx1,ry0,rz0);
00251         a = Mathf::lerp(t, u, v);
00252 
00253         q = g3[ b01 + bz0 ] ; u = at3(rx0,ry1,rz0);
00254         q = g3[ b11 + bz0 ] ; v = at3(rx1,ry1,rz0);
00255         b = Mathf::lerp(t, u, v);
00256 
00257         c = Mathf::lerp(sy, a, b);
00258 
00259         q = g3[ b00 + bz1 ] ; u = at3(rx0,ry0,rz1);
00260         q = g3[ b10 + bz1 ] ; v = at3(rx1,ry0,rz1);
00261         a = Mathf::lerp(t, u, v);
00262 
00263         q = g3[ b01 + bz1 ] ; u = at3(rx0,ry1,rz1);
00264         q = g3[ b11 + bz1 ] ; v = at3(rx1,ry1,rz1);
00265         b = Mathf::lerp(t, u, v);
00266 
00267         d = Mathf::lerp(sy, a, b);
00268 
00269         return Mathf::lerp(sz, c, d);
00270 }
00271 
00272 static void normalize2(float v[2])
00273 {
00274     float s = (float) sqrt(v[0] * v[0] + v[1] * v[1]);
00275     v[0] = v[0] / s;
00276     v[1] = v[1] / s;
00277 }
00278 
00279 static void normalize3(float v[3])
00280 {
00281     float s = (float) sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
00282     v[0] = v[0] / s;
00283     v[1] = v[1] / s;
00284     v[2] = v[2] / s;
00285 }
00286 
00287 
00288 static void init()
00289 {
00290     int i, j, k;
00291 
00292     for (i = 0; i < B; i++)
00293     {
00294         g1[i]    = Mathf::sfrand();
00295 
00296         g2[i][0] = Mathf::sfrand();
00297         g2[i][1] = Mathf::sfrand();
00298         normalize2(g2[i]);
00299 
00300         g3[i][0] = Mathf::sfrand();
00301         g3[i][1] = Mathf::sfrand();
00302         g3[i][2] = Mathf::sfrand();
00303         normalize3(g3[i]);
00304     }
00305 
00306     // Fill the permutation array with values . . .
00307     for (i = 0; i < B; i++)
00308         p[i] = i;
00309 
00310     // . . . and then shuffle it
00311     for (i = 0; i < B; i++)
00312     {
00313         k = p[i];
00314         j = rand() % B;
00315         p[i] = p[j];
00316         p[j] = k;
00317     }
00318 
00319     // Duplicate values to accelerate table lookups
00320     for (i = 0; i < B + 2; i++) 
00321     {
00322         p[B + i] = p[i];
00323         g1[B + i]    = g1[i];
00324         g2[B + i][0] = g2[i][0];
00325         g2[B + i][1] = g2[i][1];
00326         g3[B + i][0] = g3[i][0];
00327         g3[B + i][1] = g3[i][1];
00328         g3[B + i][2] = g3[i][2];
00329     }
00330 
00331     initialized = true;
00332 }
00333 

Generated on Sat Jan 14 22:30:32 2006 for Celestia by  doxygen 1.4.1