Advertisement
Guest User

Olsen Noise Algorithm C++

a guest
Feb 17th, 2015
211
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.84 KB | None | 0 0
  1. /*
  2.  * @author Tat
  3.  * c++ rewrite vivienne (WIP)
  4.  */
  5.  
  6. #include <iostream>
  7. #include <vector>
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <png++/png.hpp>
  12.  
  13. using namespace std;
  14.  
  15. void SaveTerrFile(const int * image, int size, char * filename);
  16.  
  17.  
  18. class OlsenNoise2D
  19. {
  20.  
  21. public:
  22.    int * olsennoise(int x, int y, int width, int height);
  23.  
  24. private:
  25.     int hashrandom(std::vector<int> elements);
  26.     long long hash(long long v);
  27.  
  28. };
  29.  
  30. int * OlsenNoise2D::olsennoise(int x, int y, int width, int height)
  31. {
  32.     int maxiterations = 7;
  33.     int cx, cy;
  34.     int cxh, cyh;
  35.     int cwidth, cheight;
  36.     int xoff, yoff;
  37.     int nwidth, nheight;
  38.     int nx, ny;
  39.     int nxh, nyh;
  40.     int m=0;
  41.     int n=0;
  42.     int * field = NULL;
  43.  
  44.     for (int iteration = 0; iteration < maxiterations; iteration++)
  45.     {
  46.         nx = x;
  47.         ny = y;
  48.  
  49.         nxh = x + width;
  50.         nyh = y + width;
  51.  
  52.         n = maxiterations - iteration;
  53.  
  54.         for (int i = 1; i < n; i++)
  55.         {
  56.             nx = (nx / 2) - 1;
  57.             ny = (ny / 2) - 1;
  58.             nxh = 1 -(-nxh/2);
  59.             nyh = 1 -(-nyh/2);
  60.         }
  61.  
  62.         xoff = -2*((nx/2)) + nx + 1;
  63.         yoff = -2*((ny/2)) + ny + 1;
  64.  
  65.         cx = (nx / 2) - 1;
  66.         cy = (ny / 2) - 1;
  67.         cxh = 1 -(-nxh/2);
  68.         cyh = 1 -(-nyh/2);
  69.  
  70.         nwidth = nxh - nx;
  71.         nheight = nyh - ny;
  72.  
  73.         cwidth = cxh - cx;
  74.         cheight = cyh - cy;
  75.  
  76.  
  77.         /// Field
  78.         m=cwidth;
  79.         n=cheight;
  80.  
  81.         if (field == NULL) field = new int[m*(n*m)];
  82.  
  83.         for (int j = 0; j < m; j++)
  84.         {
  85.             for (int k = 0; k < n; k++)
  86.             {
  87.                field[j+(k*m)] += (hashrandom({cx + j, cy + k, iteration}) & (1 << (7 - iteration)));
  88.             }
  89.         }
  90.  
  91.         /// Up sampled
  92.         //m=field.length * 2;
  93.         //n=field[0].length * 2;
  94.         m=cwidth*2;
  95.         n=cheight*2;
  96.  
  97.         SaveTerrFile(field, cheight, "rgbOlsena.png");
  98.  
  99.         int * upsampled = new int[m*(n*m)];
  100.  
  101.         for (int j = 0; j < m; j++)
  102.         {
  103.             for (int k = 0; k < n; k++)
  104.             {
  105.                 upsampled[j+(k*m)] = field[(j / 2)+((k / 2)*cwidth)];
  106.             }
  107.         }
  108.         field = upsampled;
  109.  
  110.         /// Blur field
  111.         //int m=field.length - 2;
  112.         //int n=field[0].length - 2;
  113.         m=cwidth-2;
  114.         n=cheight-2;
  115.  
  116.         int * blurfield = new int[m*(n*m)];
  117.  
  118.         for (int j = 0; j < m; j++)
  119.         {
  120.             for (int k = 0;  k < n; k++)
  121.             {
  122.                 for (int h = 0; h < 9; h++)
  123.                 {
  124.                     blurfield[j+(k*m)] += field[(j + (h % 3))+((k + (h / 3))*(cheight*2))];
  125.                 }
  126.                 blurfield[j+(k*m)] /= 9;
  127.             }
  128.         }
  129.         field = blurfield;
  130.  
  131.         /// Trim field
  132.         m=nwidth;
  133.         n=nheight;
  134.  
  135.         int * trimfield = new int[m*(n*m)];
  136.  
  137.         for (int j = 0;j < m; j++)
  138.         {
  139.             for (int k = 0; k < n; k++)
  140.             {
  141.                 trimfield[j+(k*m)] = field[(j + xoff)+((k + yoff)*(nheight-2))];
  142.             }
  143.         }
  144.         field = trimfield;
  145.     }
  146.     return field;
  147. }
  148.  
  149. int OlsenNoise2D::hashrandom(std::vector<int> elements)
  150. {
  151.     long long hashcalc = 0;
  152.  
  153.     for (int i = 0; i < elements.size(); i++)
  154.     {
  155.         hashcalc ^= elements[i];
  156.         hashcalc = hash(hashcalc);
  157.     }
  158.     return (int) hashcalc;
  159. };
  160.  
  161. long long OlsenNoise2D::hash(long long v)
  162. {
  163.     long hash = v;
  164.     long h = hash;
  165.  
  166.     switch ((int) hash & 3)
  167.     {
  168.     case 3:
  169.         hash += h;
  170.         hash ^= hash << 32;
  171.         hash ^= h << 36;
  172.         hash += hash >> 22;
  173.         break;
  174.     case 2:
  175.         hash += h;
  176.         hash ^= hash << 22;
  177.         hash += hash >> 34;
  178.         break;
  179.     case 1:
  180.         hash += h;
  181.         hash ^= hash << 20;
  182.         hash += hash >> 2;
  183.     }
  184.     hash ^= hash << 6;
  185.     hash += hash >> 10;
  186.     hash ^= hash << 8;
  187.     hash += hash >> 34;
  188.     hash ^= hash << 50;
  189.     hash += hash >> 12;
  190.     return hash;
  191. };
  192.  
  193.  
  194. int main()
  195. {
  196.     /// Test
  197.     int ImageSize=2048;
  198.  
  199.     int * imageInput = new int[ImageSize*ImageSize];
  200.  
  201.     /// Image
  202.     OlsenNoise2D testingolsen;
  203.     imageInput=testingolsen.olsennoise(0,0,ImageSize,ImageSize);
  204.  
  205.  
  206.     SaveTerrFile(imageInput, ImageSize, "rgbOlsen.png");
  207.  
  208.     return 1;
  209. }
  210.  
  211.  
  212. void SaveTerrFile(const int * image, int size, char * filename)
  213. {
  214.     png::image< png::rgb_pixel > newimage(size, size);
  215.  
  216.     for (unsigned int y = 0; y < newimage.get_width(); ++y)
  217.     {
  218.         for (unsigned int x = 0; x < newimage.get_height(); ++x)
  219.         {
  220.             int col = int(image[x+(y*newimage.get_width())]);
  221.             newimage[y][x] = png::rgb_pixel(col,col,col);
  222.             // non-checking equivalent of image.set_pixel(x, y, ...);
  223.         }
  224.     }
  225.  
  226.     newimage.write(filename);
  227. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement