home *** CD-ROM | disk | FTP | other *** search
/ RISC DISC 3 / RISC_DISC_3.iso / resources / etexts / gems / gemsv / ch7_1 / wave.c next >
Encoding:
C/C++ Source or Header  |  1995-04-04  |  3.6 KB  |  153 lines

  1. /* ------------------------------------------------------------------------- *\
  2.    WAVE.C :
  3.  
  4.    This package provides 3 routines for generating rectangular-like,
  5.    triangular-like and sine-like waves including specific features.
  6.  
  7.    by Christophe Schlick (10 September 1993)
  8.  
  9.    "Wave Generators for Procedural Techniques in Computer Graphics"
  10.    in Graphics Gems V (edited by A. Paeth), Academic Press
  11. \* ------------------------------------------------------------------------- */
  12.  
  13. #include <math.h>
  14. #include "wave.h"
  15.  
  16. /*
  17. ** Macro functions
  18. */
  19.  
  20. #define ABS(a)          ((a) < 0 ? -(a) : (a))
  21. #define FLOOR(a)        ((a) < 0 ? (int) ((a)-1.0) : (int) (a))
  22. #define MAX(a,b)        ((a) > (b) ? (a) : (b))
  23. #define MIN(a,b)        ((a) < (b) ? (a) : (b))
  24.  
  25. /*
  26. ** rnd : Random function (adapted from Greg Ward in Graphics Gems II)
  27. */
  28.  
  29. #define FRND(a)         rnd (17*(a))
  30. #define ARND(a)         rnd (97*(a))
  31.  
  32. static double rnd (register long s)
  33. {
  34.   s = s << 13 ^ s;
  35.   return (((s*(s*s*15731+789221)+1376312589) & 0X7FFFFFFF) / 2147483648.0);
  36. }
  37.  
  38. /*
  39. ** Rwave : Rectangular-like monodimensional wave
  40. **
  41. ** Input : t = Wave function parameter
  42. **         s = Shape parameter (in [-1,1])
  43. **         f = Frequency variance (in [0,1])
  44. **         a = Amplitude variance (in [0,1])
  45. */
  46.  
  47. double Rwave (register double t, double s, double f, double a)
  48. {
  49.   register int    i, j;
  50.   register double b;
  51.  
  52.   i = j = FLOOR (t); t -= i; j++;
  53.  
  54.   if (f) {
  55.     a = (FRND (i) - 0.5) * f;
  56.     b = (FRND (j) - 0.5) * f + 1.0;
  57.     t = (t-a) / (b-a);
  58.   }
  59.  
  60.   if (i & 1) {i++; j--; t = 1.0-t;}
  61.   t = (s < 0.0) ? (t+s*t) / (1.0+s*t) : (s > 0.0) ? t / (1.0-s+s*t) : t;
  62.   t = t < 0.5 ? 0.0 : 1.0;
  63.  
  64.   if (a) {
  65.     a = ARND (i) * a * 0.5;
  66.     b = ARND (j) * a * 0.5;
  67.     t = a + t * (1.0-a-b);
  68.   }
  69.   return (t);
  70. }
  71.  
  72. /*
  73. ** Twave : Triangular-like monodimensional wave
  74. **
  75. ** Input : t = Wave function parameter
  76. **         s = Shape parameter (in [-1,1])
  77. **         f = Frequency variance (in [0,1])
  78. **         a = Amplitude variance (in [0,1])
  79. */
  80.  
  81. double Twave (register double t, double s, double f, double a) {
  82.   register int    i, j;
  83.   register double b;
  84.  
  85.   i = j = FLOOR (t); t -= i; j++;
  86.  
  87.   if (f) {
  88.     a = (FRND (i) - 0.5) * f;
  89.     b = (FRND (j) - 0.5) * f + 1.0;
  90.     if (t < a) {
  91.       i--; j--; t++; a++;
  92.       b = a; a = (FRND (i) - 0.5) * f;
  93.     } else if (t > b) {
  94.       i++; j++; t--; b--;
  95.       a = b; b = (FRND (j) - 0.5) * f + 1.0;
  96.     }
  97.     t = (t-a) / (b-a);
  98.   }
  99.  
  100.   if (i & 1) {i++; j--; t = 1.0-t;}
  101.   t = (s < 0.0) ? (t+s*t) / (1.0+s*t) : (s > 0.0) ? t / (1.0-s+s*t) : t;
  102.  
  103.   if (a) {
  104.     a = ARND(i) * a * 0.5;
  105.     b = ARND(j) * a * 0.5;
  106.     t = a + t * (1.0-a-b);
  107.   }
  108.   return (t);
  109. }
  110.  
  111. /*
  112. ** Swave : sinusoidal-like monodimensional wave
  113. **
  114. ** Input : t = Wave function parameter
  115. **         s = Shape parameter (in [-1,1])
  116. **         f = Frequency variance (in [0,1])
  117. **         a = Amplitude variance (in [0,1])
  118. */
  119.  
  120. double Swave (register double t, double s, double f, double a)
  121. {
  122.   register int    i, j;
  123.   register double b;
  124.  
  125.   i = j = FLOOR (t); t -= i; j++;
  126.  
  127.   if (f) {
  128.     a = (FRND (i) - 0.5) * f;
  129.     b = (FRND (j) - 0.5) * f + 1.0;
  130.     if (t < a) {
  131.       i--; j--; t++; a++;
  132.       b = a; a = (FRND (i) - 0.5) * f;
  133.     } else if (t > b) {
  134.       i++; j++; t--; b--;
  135.       a = b; b = (FRND (j) - 0.5) * f + 1.0;
  136.     }
  137.     t = (t-a) / (b-a);
  138.   }
  139.  
  140.   if (i & 1) {i++; j--; t = 1.0-t;}
  141.   t = (s < 0.0) ? (t+s*t) / (1.0+s*t) : (s > 0.0) ? t / (1.0-s+s*t) : t;
  142.   t *= t * (3.0-t-t);
  143.  
  144.   if (a) {
  145.     a = ARND(i) * a * 0.5;
  146.     b = ARND(j) * a * 0.5;
  147.     t = a + t * (1.0-a-b);
  148.   }
  149.   return (t);
  150. }
  151.  
  152. /* ------------------------------------------------------------------------- */
  153.