home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / unofficial-plug-ins / mathmap / noise.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-04-21  |  2.5 KB  |  120 lines

  1. /*
  2.  * noise.c
  3.  *
  4.  * MathMap
  5.  *
  6.  * Copyright (C) 1997-2000 Mark Probst
  7.  *
  8.  * This program is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU General Public License
  10.  * as published by the Free Software Foundation; either version 2
  11.  * of the License, or (at your option) any later version.
  12.  *
  13.  * This program is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  * GNU General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU General Public License
  19.  * along with this program; if not, write to the Free Software
  20.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23. #include <math.h>
  24. #include <stdlib.h>
  25. #include <assert.h>
  26.  
  27. #include "noise.h"
  28.  
  29. #define G_SIZE         256
  30.  
  31. #define frandom()      (random() / (float)0x7fffffff)
  32. #define sfrandom()     (frandom() * 2.0 - 1.0)
  33.  
  34. #define fold(i,j,k)    (p[(p[(p[(i) % G_SIZE] + (j)) % G_SIZE] + (k)) % G_SIZE])
  35. #define drop(t)        (1.0 - 3.0 * (t) * (t) + 2.0 * fabs((t) * (t) * (t)))
  36.  
  37. float g[G_SIZE][3];
  38. int p[G_SIZE];
  39.  
  40. static float
  41. wavelet (int i, int j, int k, float x, float y, float z)
  42. {
  43.     float u, v, w;
  44.     float sigma;
  45.     int f;
  46.  
  47.     u = x - i;
  48.     v = y - j;
  49.     w = z - k;
  50.  
  51.     sigma = drop(u) * drop(v) * drop(w);
  52.  
  53.     f = fold(i, j, k);
  54.  
  55.     return sigma * (g[f][0] * u + g[f][1] * v + g[f][2] * w);
  56. }
  57.  
  58. float
  59. noise (float x, float y, float z)
  60. {
  61.     int i, j, k;
  62.  
  63.     if (x < 0)
  64.     x = x + G_SIZE * ceil(-x / G_SIZE);
  65.     if (y < 0)
  66.     y = y + G_SIZE * ceil(-y / G_SIZE);
  67.     if (z < 0)
  68.     z = z + G_SIZE * ceil(-z / G_SIZE);
  69.  
  70.     i = (int)floor(x);
  71.     j = (int)floor(y);
  72.     k = (int)floor(z);
  73.  
  74.     return wavelet(i, j, k, x, y, z)
  75.     + wavelet(i + 1, j, k, x, y, z)
  76.     + wavelet(i, j + 1, k, x, y, z)
  77.     + wavelet(i, j, k + 1, x, y, z)
  78.     + wavelet(i + 1, j + 1, k, x, y, z)
  79.     + wavelet(i + 1, j, k + 1, x, y, z)
  80.     + wavelet(i, j + 1, k + 1, x, y, z)
  81.     + wavelet(i + 1, j + 1, k + 1, x, y, z);
  82. }
  83.  
  84. void
  85. init_noise (void)
  86. {
  87.     int i;
  88.  
  89.     for (i = 0; i < G_SIZE; ++i)
  90.     {
  91.     float x, y, z;
  92.     float sql, l;
  93.  
  94.     do
  95.     {
  96.         x = sfrandom();
  97.         y = sfrandom();
  98.         z = sfrandom();
  99.         sql = x * x + y * y + z * z;
  100.     } while (sql > 1.0);
  101.  
  102.     l = sqrt(sql);
  103.     g[i][0] = x / l;
  104.     g[i][1] = y / l;
  105.     g[i][2] = z / l;
  106.     }
  107.  
  108.     for (i = 0; i < G_SIZE; ++i)
  109.     p[i] = i;
  110.     for (i = 0; i < G_SIZE; ++i)
  111.     {
  112.     int j = random() % G_SIZE;
  113.     int t;
  114.  
  115.     t = p[i];
  116.     p[i] = p[j];
  117.     p[j] = t;
  118.     }
  119. }
  120.