home *** CD-ROM | disk | FTP | other *** search
/ RISC DISC 3 / RISC_DISC_3.iso / resources / etexts / gems / gemsii / noise3.c < prev    next >
C/C++ Source or Header  |  1992-09-24  |  4KB  |  183 lines

  1. /* Copyright (c) 1988 Regents of the University of California */
  2.  
  3. #ifndef lint
  4. static char SCCSid[] = "@(#)noise3.c 2.1 11/12/91 LBL";
  5. #endif
  6.  
  7. /*
  8.  *  noise3.c - noise functions for random textures.
  9.  *
  10.  *     Credit for the smooth algorithm goes to Ken Perlin.
  11.  *     (ref. SIGGRAPH Vol 19, No 3, pp 287-96)
  12.  *
  13.  *     4/15/86
  14.  *     5/19/88    Added fractal noise function
  15.  */
  16.  
  17.  
  18. #define  A        0
  19. #define  B        1
  20. #define  C        2
  21. #define  D        3
  22.  
  23. #define  rand3a(x,y,z)    frand(67*(x)+59*(y)+71*(z))
  24. #define  rand3b(x,y,z)    frand(73*(x)+79*(y)+83*(z))
  25. #define  rand3c(x,y,z)    frand(89*(x)+97*(y)+101*(z))
  26. #define  rand3d(x,y,z)    frand(103*(x)+107*(y)+109*(z))
  27.  
  28. /* hermite */
  29. #define  hpoly1(t)    ((2.0*t-3.0)*t*t+1.0)
  30. #define  hpoly2(t)    (-2.0*t+3.0)*t*t
  31. #define  hpoly3(t)    ((t-2.0)*t+1.0)*t
  32. #define  hpoly4(t)    (t-1.0)*t*t
  33.  
  34. double  *noise3(), fnoise3(), frand();
  35.  
  36. static  interpolate();
  37.  
  38. static long  xlim[3][2];
  39. static double  xarg[3];
  40.  
  41. #define  EPSILON    .0001        /* error allowed in fractal */
  42.  
  43. #define  frand3(x,y,z)    frand(17*(x)+23*(y)+29*(z))
  44.  
  45.  
  46. double *
  47. noise3(xnew)            /* compute the noise function */
  48. register double  xnew[3];
  49. {
  50.     extern double  floor();
  51.     static double  x[3] = {-100000.0, -100000.0, -100000.0};
  52.     static double  f[4];
  53.  
  54.     if (x[0]==xnew[0] && x[1]==xnew[1] && x[2]==xnew[2])
  55.         return(f);
  56.     x[0] = xnew[0]; x[1] = xnew[1]; x[2] = xnew[2];
  57.     xlim[0][0] = floor(x[0]); xlim[0][1] = xlim[0][0] + 1;
  58.     xlim[1][0] = floor(x[1]); xlim[1][1] = xlim[1][0] + 1;
  59.     xlim[2][0] = floor(x[2]); xlim[2][1] = xlim[2][0] + 1;
  60.     xarg[0] = x[0] - xlim[0][0];
  61.     xarg[1] = x[1] - xlim[1][0];
  62.     xarg[2] = x[2] - xlim[2][0];
  63.     interpolate(f, 0, 3);
  64.     return(f);
  65. }
  66.  
  67.  
  68. static
  69. interpolate(f, i, n)
  70. double  f[4];
  71. register int  i, n;
  72. {
  73.     double  f0[4], f1[4], hp1, hp2;
  74.  
  75.     if (n == 0) {
  76.         f[A] = rand3a(xlim[0][i&1],xlim[1][i>>1&1],xlim[2][i>>2]);
  77.         f[B] = rand3b(xlim[0][i&1],xlim[1][i>>1&1],xlim[2][i>>2]);
  78.         f[C] = rand3c(xlim[0][i&1],xlim[1][i>>1&1],xlim[2][i>>2]);
  79.         f[D] = rand3d(xlim[0][i&1],xlim[1][i>>1&1],xlim[2][i>>2]);
  80.     } else {
  81.         n--;
  82.         interpolate(f0, i, n);
  83.         interpolate(f1, i | 1<<n, n);
  84.         hp1 = hpoly1(xarg[n]); hp2 = hpoly2(xarg[n]);
  85.         f[A] = f0[A]*hp1 + f1[A]*hp2;
  86.         f[B] = f0[B]*hp1 + f1[B]*hp2;
  87.         f[C] = f0[C]*hp1 + f1[C]*hp2;
  88.         f[D] = f0[D]*hp1 + f1[D]*hp2 +
  89.                 f0[n]*hpoly3(xarg[n]) + f1[n]*hpoly4(xarg[n]);
  90.     }
  91. }
  92.  
  93.  
  94. double
  95. frand(s)            /* get random number from seed */
  96. register long  s;
  97. {
  98.     s = s<<13 ^ s;
  99.     return(1.0-((s*(s*s*15731+789221)+1376312589)&0x7fffffff)/1073741824.0);
  100. }
  101.  
  102.  
  103. double
  104. fnoise3(p)            /* compute fractal noise function */
  105. double  p[3];
  106. {
  107.     double  floor();
  108.     long  t[3], v[3], beg[3];
  109.     double  fval[8], fc;
  110.     int  branch;
  111.     register long  s;
  112.     register int  i, j;
  113.                         /* get starting cube */
  114.     s = (long)(1.0/EPSILON);
  115.     for (i = 0; i < 3; i++) {
  116.         t[i] = s*p[i];
  117.         beg[i] = s*floor(p[i]);
  118.     }
  119.     for (j = 0; j < 8; j++) {
  120.         for (i = 0; i < 3; i++) {
  121.             v[i] = beg[i];
  122.             if (j & 1<<i)
  123.                 v[i] += s;
  124.         }
  125.         fval[j] = frand3(v[0],v[1],v[2]);
  126.     }
  127.                         /* compute fractal */
  128.     for ( ; ; ) {
  129.         fc = 0.0;
  130.         for (j = 0; j < 8; j++)
  131.             fc += fval[j];
  132.         fc *= 0.125;
  133.         if ((s >>= 1) == 0)
  134.             return(fc);        /* close enough */
  135.         branch = 0;
  136.         for (i = 0; i < 3; i++) {    /* do center */
  137.             v[i] = beg[i] + s;
  138.             if (t[i] > v[i]) {
  139.                 branch |= 1<<i;
  140.             }
  141.         }
  142.         fc += s*EPSILON*frand3(v[0],v[1],v[2]);
  143.         fval[~branch & 7] = fc;
  144.         for (i = 0; i < 3; i++) {    /* do faces */
  145.             if (branch & 1<<i)
  146.                 v[i] += s;
  147.             else
  148.                 v[i] -= s;
  149.             fc = 0.0;
  150.             for (j = 0; j < 8; j++)
  151.                 if (~(j^branch) & 1<<i)
  152.                     fc += fval[j];
  153.             fc = 0.25*fc + s*EPSILON*frand3(v[0],v[1],v[2]);
  154.             fval[~(branch^1<<i) & 7] = fc;
  155.             v[i] = beg[i] + s;
  156.         }
  157.         for (i = 0; i < 3; i++) {    /* do edges */
  158.             j = (i+1)%3;
  159.             if (branch & 1<<j)
  160.                 v[j] += s;
  161.             else
  162.                 v[j] -= s;
  163.             j = (i+2)%3;
  164.             if (branch & 1<<j)
  165.                 v[j] += s;
  166.             else
  167.                 v[j] -= s;
  168.             fc = fval[branch & ~(1<<i)];
  169.             fc += fval[branch | 1<<i];
  170.             fc = 0.5*fc + s*EPSILON*frand3(v[0],v[1],v[2]);
  171.             fval[branch^1<<i] = fc;
  172.             j = (i+1)%3;
  173.             v[j] = beg[j] + s;
  174.             j = (i+2)%3;
  175.             v[j] = beg[j] + s;
  176.         }
  177.         for (i = 0; i < 3; i++)        /* new cube */
  178.             if (branch & 1<<i)
  179.                 beg[i] += s;
  180.     }
  181. }
  182.  
  183.