#include // pow() #include "iwa_noise1234.h" namespace { double perlin_noise_3d_(const double x, const double y, const double z, const int octaves_start // 0<= , const int octaves_end // 0<= , const double persistence // Not 0 // 1/4 or 1/2 or 1/sqrt(3) or 1/sqrt(2) or 1 or ... ) { double total = 0; Noise1234 pn; for (int ii = octaves_start; ii <= octaves_end; ++ii) { const double frequency = pow(2.0, ii); // 1,2,4,8... const double amplitude = pow(persistence, ii); total += pn.noise(x * frequency, y * frequency, z * frequency) * amplitude; } return total; } double perlin_noise_minmax_(const int octaves_start // 0<= , const int octaves_end // 0<= , const double persistence // Not 0 // 1/4 or 1/2 or 1/sqrt(3) or 1/sqrt(2) or 1 or ... ) { double total = 0; for (int ii = octaves_start; ii <= octaves_end; ++ii) { total += pow(persistence, ii); } return total; } } //-------------------------------------------------------------------- #include // std::domain_error(-) #include // std::numeric_limits #include "igs_ifx_common.h" /* igs::image::rgba */ #include "igs_perlin_noise.h" namespace { template void change_(T *image_array, const int height // pixel , const int width // pixel , const int channels, const bool alpha_rendering_sw, const double a11 // geometry of 2D affine transformation , const double a12, const double a13, const double a21, const double a22, const double a23, const double zz, const int octaves_start // 0<= , const int octaves_end // 0<= , const double persistence // Not 0 ) { const int max_div = std::numeric_limits::max(); const int max_div_2 = max_div / 2; // 255 / 2 --> 127 // 65535 / 2 --> 32767 // const double max_mul = static_cast(max_div_2+0.999999); // const double max_off = static_cast(max_div_2+1); const double max_mul = static_cast(max_div_2 + 0.499999); const double max_off = static_cast(max_div_2 + 1.5); /* -1 .............. 0 ......... 1 x127+0.499999 ------------------------------------------ -127+0.499999 ... 0 ......... 127+0.499999 +127+1.5 ... 127+1.5 ... 127+1.5 ------------------------------------------ 1.000001 ........ 127+1.5 ... 255.999999 integer ------------------------------------------ 1 ............... 128 ....... 255 */ const double maxi = perlin_noise_minmax_(octaves_start, octaves_end, persistence); using namespace igs::image::rgba; T *image_crnt = image_array; for (int yy = 0; yy < height; ++yy) { for (int xx = 0; xx < width; ++xx, image_crnt += channels) { const T val = static_cast( perlin_noise_3d_(xx * a11 + yy * a12 + a13, xx * a21 + yy * a22 + a23, zz, octaves_start, octaves_end, persistence) / maxi * max_mul + max_off); for (int zz = 0; zz < channels; ++zz) { if (!alpha_rendering_sw && (alp == zz)) { image_crnt[zz] = static_cast(max_div); } else { image_crnt[zz] = val; } } } } } } // #include "igs_geometry2d.h" void igs::perlin_noise::change( unsigned char *image_array, const int height // pixel , const int width // pixel , const int channels, const int bits, const bool alpha_rendering_sw, const double a11 // geometry of 2D affine transformation , const double a12, const double a13, const double a21, const double a22, const double a23, const double zz, const int octaves_start // 0... , const int octaves_end // 0... , const double persistence // not 0 ) { // igs::geometry2d::affine af(a11 , a12 , a13 , a21 , a22 , a23); // igs::geometry2d::translate(); if (std::numeric_limits::digits == bits) { change_(image_array, height, width, channels, alpha_rendering_sw, a11, a12, a13, a21, a22, a23, zz, octaves_start, octaves_end, persistence); } else if (std::numeric_limits::digits == bits) { change_(reinterpret_cast(image_array), height, width, channels, alpha_rendering_sw, a11, a12, a13, a21, a22, a23, zz, octaves_start, octaves_end, persistence); } else { throw std::domain_error("Bad bits,Not uchar/ushort"); } }