Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_MATH_NOISE_NOISE_PERLIN_H
00002 #define OPENTISSUE_CORE_MATH_NOISE_NOISE_PERLIN_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/core/math/math_random.h>
00013
00014 namespace OpenTissue
00015 {
00016
00017 namespace noise
00018 {
00019
00024 template<typename real_type_>
00025 class PerlinNoise
00026 {
00027 public:
00028
00029 typedef real_type_ real_type;
00030
00031 private:
00032
00033 int * m_P;
00034 real_type * m_G2x;
00035 real_type * m_G2y;
00036
00037 real_type * m_G3x;
00038 real_type * m_G3y;
00039 real_type * m_G3z;
00040
00041 public:
00042
00043 PerlinNoise()
00044 {
00045 math::Random<real_type> random(0.0,1.0);
00046
00047
00048 m_G2x = new real_type[256];
00049 m_G2y = new real_type[256];
00050 for(int i=0;i<256;++i)
00051 {
00052 real_type r2= static_cast<real_type>(0.0);
00053 do
00054 {
00055 m_G2x[i] = random() - 0.5;
00056 m_G2y[i] = random() - 0.5;
00057 r2 = m_G2x[i]*m_G2x[i] + m_G2y[i]*m_G2y[i];
00058 }
00059 while(!(r2>0));
00060 real_type r = static_cast<real_type>( std::sqrt(r2) );
00061 m_G2x[i] /= r;
00062 m_G2y[i] /= r;
00063 }
00064
00065
00066 m_G3x = new real_type[256];
00067 m_G3y = new real_type[256];
00068 m_G3z = new real_type[256];
00069 for(int i=0;i<256;++i)
00070 {
00071 real_type r2= static_cast<real_type>(0.0);
00072 do
00073 {
00074 m_G3x[i] = random() - 0.5;
00075 m_G3y[i] = random() - 0.5;
00076 m_G3z[i] = random() - 0.5;
00077 r2 = m_G3x[i]*m_G3x[i] + m_G3y[i]*m_G3y[i] + m_G3z[i]*m_G3z[i];
00078 }
00079 while(!(r2>0));
00080
00081 real_type r = static_cast<real_type>( std::sqrt(r2) );
00082 m_G3x[i] /= r;
00083 m_G3y[i] /= r;
00084 m_G3z[i] /= r;
00085 }
00086
00087
00088 m_P = new int[256];
00089 for(int i=0;i<256;++i)
00090 m_P[i] = i;
00091 for(int i=0;i<256;++i)
00092 {
00093 int j = static_cast<int>( random()*255.0 );
00094 int s = m_P[i];
00095 m_P[i] = m_P[j];
00096 m_P[j] = s;
00097 }
00098 }
00099
00100
00101 ~PerlinNoise(void)
00102 {
00103 if(m_G2x)
00104 delete [] m_G2x;
00105 if(m_G2y)
00106 delete [] m_G2y;
00107 if(m_G3x)
00108 delete [] m_G3x;
00109 if(m_G3y)
00110 delete [] m_G3y;
00111 if(m_G3z)
00112 delete [] m_G3z;
00113 if(m_P)
00114 delete [] m_P;
00115 }
00116
00126 real_type operator()(real_type const & x,real_type const & y)const
00127 {
00128 int gridLowX = static_cast<int>(std::floor(x) );
00129 int gridHighX = gridLowX + 1;
00130 int gridLowY = static_cast<int>(std::floor(y) );
00131 int gridHighY = gridLowY + 1;
00132
00133 real_type g0x = m_G2x[ (gridLowX + m_P[ gridLowY & 0xFF] ) & 0xFF ];
00134 real_type g0y = m_G2y[ (gridLowX + m_P[ gridLowY & 0xFF] ) & 0xFF ];
00135 real_type g1x = m_G2x[ (gridHighX + m_P[ gridLowY & 0xFF] ) & 0xFF ];
00136 real_type g1y = m_G2y[ (gridHighX + m_P[ gridLowY & 0xFF] ) & 0xFF ];
00137 real_type g2x = m_G2x[ (gridHighX + m_P[ gridHighY & 0xFF] ) & 0xFF ];
00138 real_type g2y = m_G2y[ (gridHighX + m_P[ gridHighY & 0xFF] ) & 0xFF ];
00139 real_type g3x = m_G2x[ (gridLowX + m_P[ gridHighY & 0xFF] ) & 0xFF ];
00140 real_type g3y = m_G2y[ (gridLowX + m_P[ gridHighY & 0xFF] ) & 0xFF ];
00141
00142 real_type t0x = x - gridLowX;
00143 real_type t0y = y - gridLowY;
00144 real_type t1x = x - gridHighX;
00145 real_type t1y = y - gridLowY;
00146 real_type t2x = x - gridHighX;
00147 real_type t2y = y - gridHighY;
00148 real_type t3x = x - gridLowX;
00149 real_type t3y = y - gridHighY;
00150
00151 real_type dot0 = g0x*t0x + g0y*t0y;
00152 real_type dot1 = g1x*t1x + g1y*t1y;
00153 real_type dot2 = g2x*t2x + g2y*t2y;
00154 real_type dot3 = g3x*t3x + g3y*t3y;
00155
00156
00157 real_type sx = (3.0 - 2.0*t0x)*t0x*t0x;
00158 real_type a = dot0 + sx*(dot1-dot0);
00159 real_type b = dot3 + sx*(dot2-dot3);
00160
00161 real_type sy = (3.0 - 2.0*t0y)*t0y*t0y;
00162 real_type z = a+sy*(b-a);
00163
00164 return z;
00165 }
00166
00196 real_type operator()(real_type const & x,real_type const & y,real_type const & z)const
00197 {
00198 int gridLowX = static_cast<int>(std::floor(x) );
00199 int gridHighX = gridLowX + 1;
00200 int gridLowY = static_cast<int>(std::floor(y) );
00201 int gridHighY = gridLowY + 1;
00202 int gridLowZ = static_cast<int>(std::floor(z) );
00203 int gridHighZ = gridLowZ + 1;
00204
00205
00206 real_type g000x = m_G3x[ (gridLowX + m_P[ (gridLowY + m_P[ gridLowZ & 0xFF ] ) & 0xFF ] ) & 0xFF ];
00207 real_type g000y = m_G3y[ (gridLowX + m_P[ (gridLowY + m_P[ gridLowZ & 0xFF ] ) & 0xFF ] ) & 0xFF ];
00208 real_type g000z = m_G3z[ (gridLowX + m_P[ (gridLowY + m_P[ gridLowZ & 0xFF ] ) & 0xFF ] ) & 0xFF ];
00209 real_type g001x = m_G3x[ (gridLowX + m_P[ (gridLowY + m_P[ gridHighZ & 0xFF ] ) & 0xFF ] ) & 0xFF ];
00210 real_type g001y = m_G3y[ (gridLowX + m_P[ (gridLowY + m_P[ gridHighZ & 0xFF ] ) & 0xFF ] ) & 0xFF ];
00211 real_type g001z = m_G3z[ (gridLowX + m_P[ (gridLowY + m_P[ gridHighZ & 0xFF ] ) & 0xFF ] ) & 0xFF ];
00212 real_type g010x = m_G3x[ (gridLowX + m_P[ (gridHighY + m_P[ gridLowZ & 0xFF ] ) & 0xFF ] ) & 0xFF ];
00213 real_type g010y = m_G3y[ (gridLowX + m_P[ (gridHighY + m_P[ gridLowZ & 0xFF ] ) & 0xFF ] ) & 0xFF ];
00214 real_type g010z = m_G3z[ (gridLowX + m_P[ (gridHighY + m_P[ gridLowZ & 0xFF ] ) & 0xFF ] ) & 0xFF ];
00215 real_type g011x = m_G3x[ (gridLowX + m_P[ (gridHighY + m_P[ gridHighZ & 0xFF ] ) & 0xFF ] ) & 0xFF ];
00216 real_type g011y = m_G3y[ (gridLowX + m_P[ (gridHighY + m_P[ gridHighZ & 0xFF ] ) & 0xFF ] ) & 0xFF ];
00217 real_type g011z = m_G3z[ (gridLowX + m_P[ (gridHighY + m_P[ gridHighZ & 0xFF ] ) & 0xFF ] ) & 0xFF ];
00218 real_type g100x = m_G3x[ (gridHighX + m_P[ (gridLowY + m_P[ gridLowZ & 0xFF ] ) & 0xFF ] ) & 0xFF ];
00219 real_type g100y = m_G3y[ (gridHighX + m_P[ (gridLowY + m_P[ gridLowZ & 0xFF ] ) & 0xFF ] ) & 0xFF ];
00220 real_type g100z = m_G3z[ (gridHighX + m_P[ (gridLowY + m_P[ gridLowZ & 0xFF ] ) & 0xFF ] ) & 0xFF ];
00221 real_type g101x = m_G3x[ (gridHighX + m_P[ (gridLowY + m_P[ gridHighZ & 0xFF ] ) & 0xFF ] ) & 0xFF ];
00222 real_type g101y = m_G3y[ (gridHighX + m_P[ (gridLowY + m_P[ gridHighZ & 0xFF ] ) & 0xFF ] ) & 0xFF ];
00223 real_type g101z = m_G3z[ (gridHighX + m_P[ (gridLowY + m_P[ gridHighZ & 0xFF ] ) & 0xFF ] ) & 0xFF ];
00224 real_type g110x = m_G3x[ (gridHighX + m_P[ (gridHighY + m_P[ gridLowZ & 0xFF ] ) & 0xFF ] ) & 0xFF ];
00225 real_type g110y = m_G3y[ (gridHighX + m_P[ (gridHighY + m_P[ gridLowZ & 0xFF ] ) & 0xFF ] ) & 0xFF ];
00226 real_type g110z = m_G3z[ (gridHighX + m_P[ (gridHighY + m_P[ gridLowZ & 0xFF ] ) & 0xFF ] ) & 0xFF ];
00227 real_type g111x = m_G3x[ (gridHighX + m_P[ (gridHighY + m_P[ gridHighZ & 0xFF ] ) & 0xFF ] ) & 0xFF ];
00228 real_type g111y = m_G3y[ (gridHighX + m_P[ (gridHighY + m_P[ gridHighZ & 0xFF ] ) & 0xFF ] ) & 0xFF ];
00229 real_type g111z = m_G3z[ (gridHighX + m_P[ (gridHighY + m_P[ gridHighZ & 0xFF ] ) & 0xFF ] ) & 0xFF ];
00230
00231
00232 real_type t000x = (x - gridLowX);
00233 real_type t000y = (y - gridLowY);
00234 real_type t000z = (z - gridLowZ);
00235 real_type t001x = (x - gridLowX);
00236 real_type t001y = (y - gridLowY);
00237 real_type t001z = (z - gridHighZ);
00238 real_type t010x = (x - gridLowX);
00239 real_type t010y = (y - gridHighY);
00240 real_type t010z = (z - gridLowZ);
00241 real_type t011x = (x - gridLowX);
00242 real_type t011y = (y - gridHighY);
00243 real_type t011z = (z - gridHighZ);
00244 real_type t100x = (x - gridHighX);
00245 real_type t100y = (y - gridLowY);
00246 real_type t100z = (z - gridLowZ);
00247 real_type t101x = (x - gridHighX);
00248 real_type t101y = (y - gridLowY);
00249 real_type t101z = (z - gridHighZ);
00250 real_type t110x = (x - gridHighX);
00251 real_type t110y = (y - gridHighY);
00252 real_type t110z = (z - gridLowZ);
00253 real_type t111x = (x - gridHighX);
00254 real_type t111y = (y - gridHighY);
00255 real_type t111z = (z - gridHighZ);
00256
00257
00258 real_type dot000 = g000x*t000x + g000y*t000y + g000z*t000z;
00259 real_type dot001 = g001x*t001x + g001y*t001y + g001z*t001z;
00260 real_type dot010 = g010x*t010x + g010y*t010y + g010z*t010z;
00261 real_type dot011 = g011x*t011x + g011y*t011y + g011z*t011z;
00262 real_type dot100 = g100x*t100x + g100y*t100y + g100z*t100z;
00263 real_type dot101 = g101x*t101x + g101y*t101y + g101z*t101z;
00264 real_type dot110 = g110x*t110x + g110y*t110y + g110z*t110z;
00265 real_type dot111 = g111x*t111x + g111y*t111y + g111z*t111z;
00266
00267
00268 real_type sx = ( 3.0 - 2.0*t000x )*t000x*t000x;
00269 real_type sy = ( 3.0 - 2.0*t000y )*t000y*t000y;
00270 real_type sz = ( 3.0 - 2.0*t000z )*t000z*t000z;
00271
00272 real_type x00 = dot000 + sx*(dot100 - dot000);
00273 real_type x01 = dot001 + sx*(dot101 - dot001);
00274 real_type x10 = dot010 + sx*(dot110 - dot010);
00275 real_type x11 = dot011 + sx*(dot111 - dot011);
00276 real_type y0 = x00 + sy*(x10-x00);
00277 real_type y1 = x01 + sy*(x11-x01);
00278 real_type w = y0 + sz*(y1-y0);
00279 return w;
00280 }
00281
00282 };
00283
00284 }
00285
00286 }
00287
00288
00289 #endif