Advertisement
Tatarize

Olsen Noise Closer To Working

Feb 19th, 2015
302
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.02 KB | None | 0 0
  1. package com.photoembroidery.tat.olsennoise;
  2.  
  3.  
  4. import java.util.Arrays;
  5.  
  6. /**
  7. * Created by Tat on 2/17/2015.
  8. */
  9.  
  10. public class OlsenNoise2D {
  11.  
  12. public static void convolve(int[] pixels, int offset, int stride, int x, int y, int width, int height, int[][] matrix, int parts) {
  13. int startIndex = x + (y * stride);
  14. int lastIndex = (x + width - 1) + ((y + height - 1) * stride);
  15. int x_pos = x;
  16. int y_pos = y;
  17. int indexInc = 1;
  18. int yinc = 0;
  19. int xinc = 1;
  20.  
  21. for (int i = 0, s = width + height; i < s; i++) {
  22. if (i == width) {
  23. indexInc = stride;
  24. yinc = 1;
  25. xinc = 0;
  26. }
  27. int x_counter = x_pos;
  28. int index = startIndex;
  29. while (x_counter >= x && index <= lastIndex) {
  30. pixels[offset + index] = convolve(pixels, stride, offset + index, matrix, parts);
  31. x_counter--;
  32. index += stride - 1;
  33. }
  34. startIndex += indexInc;
  35. x_pos += xinc;
  36. y_pos += yinc;
  37. }
  38. }
  39.  
  40.  
  41. private static int crimp(int color) {
  42. return (color >= 0xFF) ? 0xFF : (color < 0) ? 0 : color;
  43. }
  44.  
  45. private static int convolve(int[] pixels, int stride, int index, int[][] matrix, int parts) {
  46. int redSum = 0;
  47. int greenSum = 0;
  48. int blueSum = 0;
  49. int pixel, factor;
  50. for (int j = 0, m = matrix.length; j < m; j++, index++) {
  51. for (int k = 0, n = matrix[j].length, q = index; k < n; k++, q += stride) {
  52. pixel = pixels[q];
  53. factor = matrix[j][k];
  54. redSum += factor * ((pixel >> 16) & 0xFF);
  55. greenSum += factor * ((pixel >> 8) & 0xFF);
  56. blueSum += factor * ((pixel) & 0xFF);
  57. }
  58. }
  59. return 0xFF000000 | ((crimp(redSum / parts) << 16) | (crimp(greenSum / parts) << 8) | (crimp(blueSum / parts)));
  60. }
  61.  
  62. //occupies same footprint
  63. private void applyNoise(int[] pixels, int stride, int x_within_field, int y_within_field, int width, int height, int iteration) {
  64. int index = 0;
  65. for (int k = 0, n = height - 1; k <= n; k++, index += stride) {
  66. for (int j = 0, m = width - 1; j <= m; j++) {
  67. int current = index + j;
  68. pixels[current] += (hashrandom(x_within_field + j, y_within_field + k, iteration) & (1 << (7 - iteration)));
  69. }
  70. }
  71. }
  72.  
  73. //requires half the height and width be good.
  74. private void applyScale(int[] pixels, int stride, int width, int height) {
  75. int index = (height - 1) * stride;
  76. for (int k = 0, n = 0 + height - 1; k <= n; n--, index -= stride) {
  77. for (int j = 0, m = width - 1; j <= m; m--) {
  78. int current = index + m;
  79. int lower = ((n / 2) * stride) + (m / 2);
  80. pixels[current] = pixels[lower];
  81. }
  82. }
  83. }
  84.  
  85.  
  86. //requires width + 1 valid, height + 1
  87. private static final int[][] blur2x2 = new int[][]{
  88. {1, 1},
  89. {1, 1},
  90. };
  91.  
  92. private void applyBlur(int[] pixels, int stride, int width, int height) {
  93. convolve(pixels, 0, stride,0,0, width, height, blur2x2, 4);
  94. }
  95.  
  96. //You need to give it an array larger than the current one. This math is just a guess at a number big enough, it's not actually the max dim the array would properly need to be.
  97. public int getRequiredDim(int dim) {
  98. return (dim + 5) * 2;
  99. }
  100. private void trim(int[] pixels, int width, int height, int[] workingpixels, int workingstride) {
  101. for (int k = 0; k < height; k++) {
  102. for (int j = 0; j < width; j++) {
  103. int index = j + (k * width);
  104. int workingindex = j + (k * workingstride);
  105. pixels[index] = workingpixels[workingindex];
  106. }
  107. }
  108. }
  109.  
  110. static final int maxiterations = 7;
  111. public void olsennoise(int[] pixels, int stride, int x, int y, int width, int height) {
  112. Arrays.fill(pixels, 0xFF000000);
  113. olsennoise(pixels, stride, x, y, width, height, maxiterations);
  114. }
  115.  
  116. public void olsennoise(int[] pixels, int stride, int x_within_field, int y_within_field, int width, int height, int iteration) {
  117. if (iteration == 0) {
  118. applyNoise(pixels, stride, x_within_field, y_within_field, width, height, iteration);
  119. return;
  120. }
  121.  
  122. olsennoise(pixels, stride, (x_within_field/2)-2, (y_within_field/2)-2, (width/2)+2, (height/2) + 2, iteration - 1);
  123.  
  124. //scale only requires (width/2+1) and (height/2+1) valid pixels.
  125. applyScale(pixels, stride, width+1, height+1);
  126.  
  127. //blur only requires width+1 and height+1 valid pixels.
  128. applyBlur(pixels, stride, width, height);
  129.  
  130. //noise requires width, and height valid pixels
  131. applyNoise(pixels, stride, x_within_field, y_within_field, width, height, iteration);
  132. }
  133.  
  134.  
  135. public static int hashrandom(int... elements) {
  136. long hash = 0;
  137. for (int i = 0; i < elements.length; i++) {
  138. hash ^= elements[i];
  139. hash = hash(hash);
  140. }
  141. return (int) hash;
  142. }
  143.  
  144. public static long hash(long v) {
  145. long hash = v;
  146. long h = hash;
  147.  
  148. switch ((int) hash & 3) {
  149. case 3:
  150. hash += h;
  151. hash ^= hash << 32;
  152. hash ^= h << 36;
  153. hash += hash >> 22;
  154. break;
  155. case 2:
  156. hash += h;
  157. hash ^= hash << 22;
  158. hash += hash >> 34;
  159. break;
  160. case 1:
  161. hash += h;
  162. hash ^= hash << 20;
  163. hash += hash >> 2;
  164. }
  165. hash ^= hash << 6;
  166. hash += hash >> 10;
  167. hash ^= hash << 8;
  168. hash += hash >> 34;
  169. hash ^= hash << 50;
  170. hash += hash >> 12;
  171. return hash;
  172. }
  173. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement