| #include <cmath> // pow() |
| #include "iwa_noise1234.h" |
| |
| namespace { |
| double perlin_noise_3d_(const double x, const double y, const double z, |
| const int octaves_start |
| , |
| const int octaves_end |
| , |
| const double persistence |
| |
| ) { |
| double total = 0; |
| Noise1234 pn; |
| for (int ii = octaves_start; ii <= octaves_end; ++ii) { |
| const double frequency = pow(2.0, ii); |
| 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 |
| , |
| const int octaves_end |
| , |
| const double persistence |
| |
| ) { |
| double total = 0; |
| for (int ii = octaves_start; ii <= octaves_end; ++ii) { |
| total += pow(persistence, ii); |
| } |
| return total; |
| } |
| } |
| |
| #include <stdexcept> // std::domain_error(-) |
| #include <limits> // std::numeric_limits |
| #include "igs_ifx_common.h" |
| #include "igs_perlin_noise.h" |
| namespace { |
| template <class T> |
| 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<T>::max(); |
| const int max_div_2 = max_div / 2; |
| // 255 / 2 --> 127 |
| // 65535 / 2 --> 32767 |
| // const double max_mul = static_cast<double>(max_div_2+0.999999); |
| |
| const double max_mul = static_cast<double>(max_div_2 + 0.499999); |
| const double max_off = static_cast<double>(max_div_2 + 1.5); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| 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<T>( |
| 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<T>(max_div); |
| } else { |
| image_crnt[zz] = val; |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| void igs::perlin_noise::change( |
| unsigned char *image_array, const int height |
| , |
| const int width |
| , |
| const int channels, const int bits, const bool alpha_rendering_sw, |
| const double a11 |
| , |
| const double a12, const double a13, const double a21, const double a22, |
| const double a23, const double zz, const int octaves_start |
| , |
| const int octaves_end |
| , |
| const double persistence |
| ) { |
| |
| |
| |
| if (std::numeric_limits<unsigned char>::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<unsigned short>::digits == bits) { |
| change_(reinterpret_cast<unsigned short *>(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"); |
| } |
| } |