Advertisement
Guest User

Untitled

a guest
Apr 27th, 2017
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.18 KB | None | 0 0
  1.  
  2. import java.util.*;
  3.  
  4. int INNER_RADIUS = 7;
  5. int OUTER_RADIUS = 3 * INNER_RADIUS;
  6. double B1 = 0.278;
  7. double B2 = 0.365;
  8. double D1 = 0.267;
  9. double D2 = 0.445;
  10. double ALPHA_N = 0.028;
  11. double ALPHA_M = 0.147;
  12. int LOG_RES = 9;
  13. int TRUE_RES = (1<<LOG_RES);
  14. int[] COLOR_SHIFT = new int[]{0, 0, 0};
  15. int[] COLOR_SCALE = new int[]{256, 256, 256};
  16. int NR_OF_FIELDS = 2;
  17.  
  18. int current_field;
  19. List<double[][]> fields = new ArrayList<double[][]>();
  20. double[][] imaginary_field, M_re_buffer, M_im_buffer, N_re_buffer, N_im_buffer;
  21. double[][] M_re, M_im, N_re, N_im;
  22.  
  23. void setup() {
  24. size(800, 800);
  25.  
  26. current_field = 0;
  27. for (int i = 0; i < NR_OF_FIELDS; i++) {
  28. fields.add(zeromatrix());
  29. }
  30. imaginary_field = zeromatrix();
  31. M_re_buffer = zeromatrix();
  32. M_im_buffer = zeromatrix();
  33. N_re_buffer = zeromatrix();
  34. N_im_buffer = zeromatrix();
  35.  
  36.  
  37. //Precalculate multipliers for m,n
  38. BesselJ inner_bessel = BesselJ(INNER_RADIUS);
  39. BesselJ outer_bessel = BesselJ(OUTER_RADIUS);
  40. double inner_w = 1.0 / inner_bessel.w;
  41. double outer_w = 1.0 / (outer_bessel.w - inner_bessel.w);
  42. M_re = inner_bessel.re;
  43. M_im = inner_bessel.im;
  44. N_re = outer_bessel.re;
  45. N_im = outer_bessel.im;
  46. for (int i=0; i < TRUE_RES; ++i) {
  47. for (int j=0; j < TRUE_RES; ++j) {
  48. N_re[i][j] = outer_w * (N_re[i][j] - M_re[i][j]);
  49. N_im[i][j] = outer_w * (N_im[i][j] - M_im[i][j]);
  50. M_re[i][j] *= inner_w;
  51. M_im[i][j] *= inner_w;
  52. }
  53. }
  54.  
  55. background(0);
  56. frameRate(30);
  57. init_field(0);
  58. speckle_field(2000, 1);
  59. }
  60.  
  61. void draw() {
  62. perform_calculation_step();
  63.  
  64. double[][] cur_field = fields.get(current_field);
  65.  
  66. if (mousePressed){
  67. int v = (int) (((double) mouseX / (double) width) * (double) TRUE_RES);
  68. int u = (int) (((double) mouseY / (double) height) * (double) TRUE_RES);
  69. for (int x = -OUTER_RADIUS/2; x < OUTER_RADIUS/2; x++) {
  70. for (int y = -OUTER_RADIUS/2; y < OUTER_RADIUS/2; y++) {
  71. cur_field[u+x][v+y] = 1;
  72. }
  73. }
  74. for (int x = -INNER_RADIUS/2; x < INNER_RADIUS/2; x++) {
  75. for (int y = -INNER_RADIUS/2; y < INNER_RADIUS/2; y++) {
  76. cur_field[u+x][v+y] = 0;
  77. }
  78. }
  79. }
  80.  
  81. int image_ptr = 0;
  82. PImage img = createImage(TRUE_RES, TRUE_RES, RGB);
  83. img.loadPixels();
  84. for (int i = 0; i < TRUE_RES; i++) {
  85. for (int j = 0; j < TRUE_RES; j++) {
  86. double s = cur_field[i][j];
  87. int[] clr = new int[]{255, 255, 255};
  88. for (int k = 0; k < 3; k++) {
  89. clr[k] = (int) Math.max(0, Math.min(255, Math.floor(COLOR_SHIFT[k] + COLOR_SCALE[k]*s)));
  90. }
  91. img.pixels[image_ptr] = color(clr[0], clr[1], clr[2]);
  92. image_ptr++;
  93. }
  94. }
  95. img.updatePixels();
  96.  
  97. //Blit to screen
  98. img.resize(width, height);
  99. image(img, 0, 0);
  100. }
  101.  
  102. void init_field(double x) {
  103. double[][] cur_field = fields.get(current_field);
  104. for (int i = 0; i < TRUE_RES; i++) {
  105. for (int j = 0; j < TRUE_RES; j++) {
  106. cur_field[i][j] = x;
  107. }
  108. }
  109. }
  110.  
  111. void speckle_field(int count, double intensity) {
  112. double[][] cur_field = fields.get(current_field);
  113. for (int i = 0; i < count; i++) {
  114. int u = (int) Math.floor(Math.random() * (TRUE_RES - INNER_RADIUS));
  115. int v = (int) Math.floor(Math.random() * (TRUE_RES - INNER_RADIUS));
  116. for (int x = 0; x < INNER_RADIUS; x++) {
  117. for (int y = 0; y < INNER_RADIUS; y++) {
  118. cur_field[u+x][v+y] = intensity;
  119. }
  120. }
  121. }
  122. }
  123.  
  124. void perform_calculation_step() {
  125. //Read in fields
  126. double[][] cur_field = fields.get(current_field);
  127. current_field = (current_field + 1) % fields.size();
  128. double[][] next_field = fields.get(current_field);
  129. //Clear extra imaginary field
  130. for (int i = 0; i < TRUE_RES; i++) {
  131. for (int j = 0; j < TRUE_RES; j++) {
  132. imaginary_field[i][j] = 0.0;
  133. }
  134. }
  135. //Compute m,n fields
  136. fft2(true, LOG_RES, cur_field, imaginary_field);
  137. field_multiply(cur_field, imaginary_field, M_re, M_im, M_re_buffer, M_im_buffer);
  138. fft2(false, LOG_RES, M_re_buffer, M_im_buffer);
  139. field_multiply(cur_field, imaginary_field, N_re, N_im, N_re_buffer, N_im_buffer);
  140. fft2(false, LOG_RES, N_re_buffer, N_im_buffer);
  141. //Step s
  142. for (int i=0; i<next_field.length; ++i) {
  143. for (int j=0; j<next_field.length; ++j) {
  144. next_field[i][j] = S(N_re_buffer[i][j], M_re_buffer[i][j]);
  145. }
  146. }
  147. }
  148.  
  149. class BesselJ {
  150. double[][] re;
  151. double[][] im;
  152. double w;
  153. BesselJ(double[][] re, double[][] im, double w) {
  154. this.re = re;
  155. this.im = im;
  156. this.w = w;
  157. }
  158. }
  159.  
  160. BesselJ BesselJ(double radius) {
  161. double[][] field = zeromatrix();
  162. double weight = 0.0;
  163. for (int i = 0; i < field.length; i++) {
  164. for (int j = 0; j < field.length; j++) {
  165. double ii = ((i + field.length/2) % field.length) - field.length/2;
  166. double jj = ((j + field.length/2) % field.length) - field.length/2;
  167. double r = Math.sqrt(ii*ii + jj*jj) - radius;
  168. double v = 1.0 / (1.0 + Math.exp(LOG_RES * r));
  169. weight += v;
  170. field[i][j] = v;
  171. }
  172. }
  173. double[][] imag_field = zeromatrix();
  174. fft2(true, LOG_RES, field, imag_field);
  175. return new BesselJ(field, imag_field, weight);
  176. }
  177.  
  178. double sigma(double x, double a, double alpha) {
  179. return 1.0 / (1.0 + Math.exp(-4.0/alpha * (x - a)));
  180. }
  181.  
  182. double sigma_2(double x, double a, double b) {
  183. return sigma(x, a, ALPHA_N) * (1.0 - sigma(x, b, ALPHA_N));
  184. }
  185.  
  186. double lerp(double a, double b, double t) {
  187. return (1.0-t)*a + t*b;
  188. }
  189.  
  190. double S(double n, double m) {
  191. double alive = sigma(m, 0.5, ALPHA_M);
  192. return sigma_2(n, lerp(B1, D1, alive), lerp(B2, D2, alive));
  193. }
  194.  
  195. void field_multiply(double[][] a_r, double[][] a_i,
  196. double[][] b_r, double[][] b_i,
  197. double[][] c_r, double[][] c_i) {
  198. for (int i = 0; i < TRUE_RES; i++) {
  199. double[] Ar = a_r[i];
  200. double[] Ai = a_i[i];
  201. double[] Br = b_r[i];
  202. double[] Bi = b_i[i];
  203. double[] Cr = c_r[i];
  204. double[] Ci = c_i[i];
  205. for (int j = 0; j < TRUE_RES; j++) {
  206. double a = Ar[j];
  207. double b = Ai[j];
  208. double c = Br[j];
  209. double d = Bi[j];
  210. double t = a * (c + d);
  211. Cr[j] = t - d*(a+b);
  212. Ci[j] = t + c*(b-a);
  213. }
  214. }
  215. }
  216.  
  217. void fft(boolean dir, int m, double[] x, double[] y) {
  218. int nn, i, i1, j, k, i2, l, l1, l2;
  219. double c1, c2, tx, ty, t1, t2, u1, u2, z;
  220. nn = x.length;
  221. /* Do the bit reversal */
  222. i2 = nn >> 1;
  223. j = 0;
  224. for (i=0; i<nn-1; i++) {
  225. if (i < j) {
  226. tx = x[i];
  227. ty = y[i];
  228. x[i] = x[j];
  229. y[i] = y[j];
  230. x[j] = tx;
  231. y[j] = ty;
  232. }
  233. k = i2;
  234. while (k <= j) {
  235. j -= k;
  236. k >>= 1;
  237. }
  238. j += k;
  239. }
  240. /* Compute the FFT */
  241. c1 = -1.0;
  242. c2 = 0.0;
  243. l2 = 1;
  244. for (l = 0; l < m; l++) {
  245. l1 = l2;
  246. l2 <<= 1;
  247. u1 = 1.0;
  248. u2 = 0.0;
  249. for (j=0; j<l1; j++) {
  250. for (i=j; i<nn; i+=l2) {
  251. i1 = i + l1;
  252. t1 = u1 * x[i1] - u2 * y[i1];
  253. t2 = u1 * y[i1] + u2 * x[i1];
  254. x[i1] = x[i] - t1;
  255. y[i1] = y[i] - t2;
  256. x[i] += t1;
  257. y[i] += t2;
  258. }
  259. z = u1 * c1 - u2 * c2;
  260. u2 = u1 * c2 + u2 * c1;
  261. u1 = z;
  262. }
  263. c2 = Math.sqrt((1.0 - c1) / 2.0);
  264. if (dir)
  265. c2 = -c2;
  266. c1 = Math.sqrt((1.0 + c1) / 2.0);
  267. }
  268. /* Scaling for forward transform */
  269. if (!dir) {
  270. double scale_f = 1.0 / nn;
  271. for (i=0; i<nn; i++) {
  272. x[i] *= scale_f;
  273. y[i] *= scale_f;
  274. }
  275. }
  276. }
  277.  
  278. void fft2(boolean dir, int m, double[][] x, double[][] y) {
  279. /* In place 2D FFT */
  280. for (int i = 0; i < x.length; ++i) {
  281. fft(dir, m, x[i], y[i]);
  282. }
  283. for (int i=0; i<x.length; ++i) {
  284. for (int j=0; j<i; ++j) {
  285. double t = x[i][j];
  286. x[i][j] = x[j][i];
  287. x[j][i] = t;
  288. }
  289. }
  290. for (int i=0; i<y.length; ++i) {
  291. for (int j=0; j<i; ++j) {
  292. double t = y[i][j];
  293. y[i][j] = y[j][i];
  294. y[j][i] = t;
  295. }
  296. }
  297. for (int i=0; i < x.length; ++i) {
  298. fft(dir, m, x[i], y[i]);
  299. }
  300. }
  301.  
  302. double[][] zeromatrix() {
  303. return matrix(TRUE_RES, TRUE_RES, 0.0);
  304. }
  305.  
  306. static double[][] matrix(int rows, int cols, double value) {
  307. double[][] matrix = new double[rows][cols];
  308. for (int row = 0; row < rows; row++)
  309. for (int col = 0; col < cols; col++)
  310. matrix[row][col] = value;
  311. return matrix;
  312. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement