home *** CD-ROM | disk | FTP | other *** search
/ RISC DISC 3 / RISC_DISC_3.iso / resources / etexts / gems / gemsv / ch7_7 / mactbox / tool.h < prev    next >
C/C++ Source or Header  |  1994-09-28  |  12KB  |  306 lines

  1. /* ------------------------------------------------------------------------- *\
  2.    TOOL.H :
  3.  
  4.    Basic definitions (based on A. Glassner in Graphics Gems I)
  5.  
  6.    by Christophe Schlick (1 June 1992)
  7.  
  8.    "A Toolbox of Macro Functions for Computer Graphics"
  9.    in Graphics Gems V (edited by A. Paeth), Academic Press
  10. \* ------------------------------------------------------------------------- */
  11.  
  12. #ifndef _TOOL_
  13. #define _TOOL_
  14.  
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <math.h>
  18.  
  19. /* ------------------------------------------------------------------------- *\
  20.                              TYPES AND CONSTANTS
  21. \* ------------------------------------------------------------------------- */
  22.  
  23. /*
  24. ** Type definitions (boolean, byte and file)
  25. */
  26.  
  27. typedef unsigned int  bool;
  28. typedef unsigned char byte;
  29. typedef FILE *file;
  30.  
  31. /*
  32. ** Boolean constants
  33. */
  34.  
  35. #define TRUE    (1)
  36. #define FALSE   (0)
  37. #define ON      (1)
  38. #define OFF     (0)
  39.  
  40. /*
  41. ** Mathematical constants
  42. */
  43.  
  44. #ifdef SINGLE_REAL
  45.  
  46. #define LO_TOL      ((float) 0.000010)
  47. #define TOL         ((float) 0.000100)
  48. #define HI_TOL      ((float) 0.001000)
  49. #define E           ((float) 2.718282)
  50. #define PI          ((float) 3.141593)
  51. #define HALF_PI     ((float) 1.570796)
  52. #define DBLE_PI     ((float) 6.283185)
  53. #define SQRT2       ((float) 1.414214)
  54. #define HALF_SQRT2  ((float) 0.707107)
  55. #define DBLE_SQRT2  ((float) 2.828427)
  56. #define SQRT3       ((float) 1.732051)
  57. #define HALF_SQRT3  ((float) 0.860254)
  58. #define DBLE_SQRT3  ((float) 3.464102)
  59. #define GOLD_RATIO  ((float) 1.618340)
  60. #define DEG_TO_RAD  ((float) 0.017453)
  61. #define RAD_TO_DEG  ((float) 57.29578)
  62.  
  63. #else
  64.  
  65. #define LO_TOL      ((double) 0.0000000000000010)
  66. #define TOL         ((double) 0.0000000000000100)
  67. #define HI_TOL      ((double) 0.0000000000001000)
  68. #define E           ((double) 2.7182818284590498)
  69. #define PI          ((double) 3.1415926535897929)
  70. #define HALF_PI     ((double) 1.5707963267948965)
  71. #define DBLE_PI     ((double) 6.2831853071795858)
  72. #define SQRT2       ((double) 1.4142135623730951)
  73. #define HALF_SQRT2  ((double) 0.7071067811865476)
  74. #define DBLE_SQRT2  ((double) 2.8284271248461902)
  75. #define SQRT3       ((double) 1.7320508075688772)
  76. #define HALF_SQRT3  ((double) 0.8602540378443859)
  77. #define DBLE_SQRT3  ((double) 3.4641016151377544)
  78. #define GOLD_RATIO  ((double) 1.6183398874989489)
  79. #define DEG_TO_RAD  ((double) 0.0174532925199433)
  80. #define RAD_TO_DEG  ((double) 57.295779513082322)
  81.  
  82. #endif
  83.  
  84. /* ------------------------------------------------------------------------- *\
  85.                                MATHEMATICAL MACROS
  86. \* ------------------------------------------------------------------------- */
  87.  
  88. /*
  89. ** ABS(t) = Absolute value of 't'
  90. ** SGN(t) = Sign value of 't'
  91. ** FLOOR(t) = Map 't' to the default integer
  92. ** ROUND(t) = Map 't' to the nearest integer
  93. */
  94.  
  95. #define ABS(t)          ((t) < 0 ? -(t) : (t))
  96. #define SGN(t)          ((t) < 0 ? -1 : (t) > 0 ? 1 : 0)
  97. #define FLOOR(t)        ((t) < 0 ? (int) ((t)-1.0) : (int) (t))
  98. #define ROUND(t)        ((t) < 0 ? (int) ((t)-0.5) : (int) ((t)+0.5))
  99.  
  100. /*
  101. ** ZERO(a)    = Test if a =  0 with a given tolerance
  102. ** SAME(a,b)  = Test if a =  b with a given tolerance
  103. ** LESS(a,b)  = Test if a <  b with a given tolerance
  104. ** MORE(a,b)  = Test if a >  b with a given tolerance
  105. ** !LESS(a,b) = Test if a >= b with a given tolerance
  106. ** !MORE(a,b) = Test if a <= b with a given tolerance
  107. ** XXXX_TOL(a,b,t) = Same thing but with a user-provided tolerance
  108. */
  109.  
  110. #define ZERO(a)         ((a) > -TOL && (a) < TOL)
  111. #define ZERO_TOL(a,t)   ((a) > -(t) && (a) < (t))
  112. #define SAME(a,b)       ((a) > (b)-TOL && (a) < (b)+TOL)
  113. #define SAME_TOL(a,b,t) ((a) > (b)-(t) && (a) < (b)+(t))
  114. #define LESS(a,b)       ((a) < (b)-TOL)
  115. #define LESS_TOL(a,b,t) ((a) < (b)-(t))
  116. #define MORE(a,b)       ((a) > (b)+TOL)
  117. #define MORE_TOL(a,b,t) ((a) > (b)+(t))
  118.  
  119. /*
  120. ** IN(t,lo,hi)    = Test if t >  lo and t <  hi
  121. ** !IN(t,lo,hi)   = Test if t <= lo  or t >= hi
  122. ** OUT(t,lo,hi)   = Test if t <  lo  or t >  hi
  123. ** !OUT(t,lo,hi)  = Test if t >= lo and t <= hi
  124. ** CLAMP(t,lo,hi) = Clamp a value 't' to the range [lo,hi]
  125. */
  126.  
  127. #define IN(t,lo,hi)     ((t) > (lo) && (t) < (hi))
  128. #define OUT(t,lo,hi)    ((t) < (lo) || (t) > (hi))
  129. #define CLAMP(t,lo,hi)  ((t) < (lo) ? (lo) : (t) > (hi) ? (hi) : (t))
  130.  
  131. /*
  132. ** MIN(a,b) = Minimum of values 'a' and 'b'
  133. ** MAX(a,b) = Maximum of values 'a' and 'b'
  134. ** MINMIN(a,b,c) = Minimum of values 'a', 'b' and 'c'
  135. ** MAXMAX(a,b,c) = Maximum of values 'a', 'b' and 'c'
  136. */
  137.  
  138. #define MIN(a,b)        ((a) < (b) ? (a) : (b))
  139. #define MAX(a,b)        ((a) > (b) ? (a) : (b))
  140. #define MINMIN(a,b,c)   ((a) < (b) ? MIN (a,c) : MIN (b,c))
  141. #define MAXMAX(a,b,c)   ((a) > (b) ? MAX (a,c) : MAX (b,c))
  142.  
  143. /*
  144. ** LERP(t,a,b) = Linear interpolation between 'a' and 'b' using 't' (0<=t<=1)
  145. ** ==> LERP(0) = a, LERP(1) = b
  146. **
  147. ** HERP(t,a,b) = Hermite interpolation between 'a' and 'b' using 't' (0<=t<=1)
  148. ** ==> HERP(0) = a, HERP'(0) = 0, HERP(1) = b, HERP'(1) = 0
  149. **
  150. ** CERP(t,a,b) = Cardinal interpolation between 'a' and 'b' using 't' (0<=t<=1)
  151. ** ==> CERP(0) = a, CERP'(0) = 0.5*(b-aa), HERP(1) = b, HERP'(1) = 0.5*(bb-a)
  152. */
  153.  
  154. #define LERP(t,a,b)       ((a) + ((b)-(a))*(t))
  155. #define HERP(t,a,b)       ((a) + ((b)-(a))*(t)*(t)*(3.0-(t)-(t)))
  156. #define CERP(t,aa,a,b,bb) ((a) + 0.5*(t)*((b)-(aa)+(t)*(2.0*(aa)-5.0*(a)\
  157.                           +4.0*(b)-(bb)+(t)*((bb)-3.0*(b)+3.0*(a)-(aa)))))
  158.  
  159. /*
  160. ** BIAS(t,p) = Rational bias operator (0 <= t <= 1 and 0 < p < 1)
  161. ** GAIN(t,p) = Rational gain operator (0 <= t <= 1 and 0 < p < 1)
  162. **
  163. ** Note : For details, see the Gem given by C. Schlick in "Graphics Gems IV"
  164. */
  165.  
  166. #define BIAS(t,p)       ((p)*(t)/((p)+((p)+(p)-1.0)*((t)-1.0)))
  167. #define GAIN(t,p)       ((t)<0.5 ? (p)*(t)/((p)+((p)+(p)-1.0)*((t)+(t)-1.0)):\
  168.              (p)*((t)-1.0)/((p)-((p)+(p)-1.0)*((t)+(t)-1.0))+1.0)
  169.  
  170. /*
  171. ** SWAP(a,b,t) = Swap 'a' and 'b' using 't' as temporary variable
  172. **
  173. ** Warning : The Gem given by B. Wyvill in "Graphics Gems I" should not be used
  174. **           because it is compiler-dependent when using non-integer variables!
  175. */
  176.  
  177. #define SWAP(a,b,t)     ((t) = (a), (a) = (b), (b) = (t))
  178.  
  179. /*
  180. ** Resolution (real solutions only) of a quadratic equation: a*x^2+b*x+c = 0
  181. **
  182. ** Warning : This is a hacker-like implementation of a quadratic solver. It
  183. **           is intended to be optimal in terms of floating point operations
  184. **           but warn that values of parameters a, b and c are destroyed!
  185. **
  186. ** Return :  a = Smallest solution (if it exists)
  187. **           b = Greatest solution (if it exists)
  188. **           Return value = Number of solutions (0, 1, or 2)
  189. */
  190.  
  191. #define QUADRATIC(a,b,c)\
  192.         (ZERO (a) ? ZERO (b) ? 0 : (a = -c / b, b = a, 1) :\
  193.          (a = -0.5 / a, b *= a, c *= a + a, c += b * b,\
  194.          (c >  TOL) ? (c = sqrt (c), a = b - c, b = b + c, 2) :\
  195.          (c < -TOL) ? 0 : (a = b, 1)))
  196.  
  197. /* ------------------------------------------------------------------------- *\
  198.                             MEMORY MANAGEMENT MACROS
  199. \* ------------------------------------------------------------------------- */
  200.  
  201. /*
  202. ** USR_INIT_MEM = User-provided memory allocation routine (default = malloc)
  203. ** USR_EXIT_MEM = User-provided memory deallocation routine (default = free)
  204. **
  205. ** Note: If you do not like standard (de)allocation routines, simply redefine
  206. **       USR_INIT_MEM and USR_EXIT_MEM with your favorite functions
  207. */
  208.  
  209. #ifndef USR_INIT_MEM
  210. #define USR_INIT_MEM  malloc
  211. #endif
  212.  
  213. #ifndef USR_EXIT_MEM
  214. #define USR_EXIT_MEM  free
  215. #endif
  216.  
  217. /*
  218. ** INIT_MEM(Var,Type,Nbr) = Allocation for 'Nbr' elements of type 'Type'
  219. ** EXIT_MEM(Var) = Deallocation of variable 'Var'
  220. ** ZERO_MEM(Var,Type,Nbr) = Fill 'Nbr' elements of type 'Type' with zero
  221. ** COPY_MEM(Var,Mem,Type,Nbr) = Copy 'Nbr' elements from 'Mem' to 'Var'
  222. ** SAME_MEM(Var,Mem,Type,Nbr) = Test if 'Var=Mem' (only 'Nbr' first elements)
  223. ** LESS_MEM(Var,Mem,Type,Nbr) = Test if 'Var<Mem' (only 'Nbr' first elements)
  224. ** MORE_MEM(Var,Mem,Type,Nbr) = Test if 'Var>Mem' (only 'Nbr' first elements)
  225. */
  226.  
  227. #define INIT_MEM(Var,Type,Nbr)     (Var = (Type*) (malloc(sizeof(Type)*(Nbr))))
  228. #define EXIT_MEM(Var)              (free (Var))
  229. #define ZERO_MEM(Var,Type,Nbr)     (bzero (Var,sizeof(Type)*(Nbr)))
  230. #define COPY_MEM(Var,Mem,Type,Nbr) (bcopy (Mem,Var,sizeof(Type)*(Nbr))))
  231. #define SAME_MEM(Var,Mem,Type,Nbr) (bcmp (Var,Mem,sizeof(Type)*(Nbr)) == 0)
  232. #define LESS_MEM(Var,Mem,Type,Nbr) (bcmp (Var,Mem,sizeof(Type)*(Nbr))  < 0)
  233. #define MORE_MEM(Var,Mem,Type,Nbr) (bcmp (Var,Mem,sizeof(Type)*(Nbr))  > 0)
  234.  
  235. /* ------------------------------------------------------------------------- *\
  236.                            FILE MANAGEMENT MACROS
  237. \* ------------------------------------------------------------------------- */
  238.  
  239. /*
  240. ** Symbolic constants for standard streams and file modes
  241. */
  242.  
  243. #define SOF stdout      /* Standard output file */
  244. #define SIF stdin       /* Standard input file */
  245. #define SEF stderr      /* Standard error file */
  246.  
  247. #define RFILE "r"       /* Open an existing file in read mode */
  248. #define WFILE "a"       /* Open an existing file in write mode */
  249. #define NFILE "w"       /* Create a new file (or recreate an existing one) */
  250.  
  251. /*
  252. ** INIT_FILE(File,Name,Mode) = Open or create file 'Name' in a given 'Mode'
  253. ** EXIT_FILE(File) = Close file 'File'
  254. ** TEST_FILE(File) = Test if the file pointer is within 'File'
  255. ** HEAD_FILE(File) = Set the file pointer at the head of 'File'
  256. ** TAIL_FILE(File) = Set the file pointer at the tail of 'File'
  257. */
  258.  
  259. #define INIT_FILE(File,Name,Mode)       ((File) = fopen (Name, Mode))
  260. #define EXIT_FILE(File)                 (fclose (File))
  261. #define TEST_FILE(File)                 (!feof (File))
  262. #define HEAD_FILE(File)                 (fseek (File, (long)0, 0))
  263. #define TAIL_FILE(File)                 (fseek (File, (long)0, 2))
  264.  
  265. /*
  266. ** GET_BYTE(File,Var) = Get a byte in 'File' and put it in 'Var'
  267. ** PUT_BYTE(File,Var) = Put a byte 'Var' at the current position in 'File'
  268. ** GET_STR(File,Var) = Get a string (until the next blank caracter) from 'File'
  269. ** PUT_STR(File,Var) = Put a null-terminated string 'Var' in 'File'
  270. ** GET_LINE(File,Var,Max) = Get a line of at most 'Max' characters from 'File'
  271. ** PUT_LINE(File,Var) = Put a string 'Var' ended with a newline char in 'File'
  272. */
  273.  
  274. #define GET_BYTE(File,Var)      ((Var) = getc (File))
  275. #define PUT_BYTE(File,Var)      (putc (Var, File))
  276. #define GET_STR(File,Var)       (fscanf (File, "%s\n", Var))
  277. #define PUT_STR(File,Var)       (fprintf (File, "%s", Var))
  278. #define GET_LINE(File,Var,Max)  (fgets (Var, Max, File))
  279. #define PUT_LINE(File,Var)      (fprintf (File, "%s\n", Var))
  280.  
  281. /* ------------------------------------------------------------------------- *\
  282.                          ERROR MANAGEMENT MACROS
  283. \* ------------------------------------------------------------------------- */
  284.  
  285. /*
  286. ** ASSERT(Test) = If 'Test' is false, display a standard error message
  287. ** WARN_ERROR(Test,Mesg,Name) = If 'Test' is false, display an error 'Mesg'
  288. **                              including an eventual identifier 'Name'
  289. ** STOP_ERROR(Test,Mesg,Name) = If 'Test' is false, display an error 'Mesg'
  290. **                              including an identifier 'Name' and stop
  291. ** CURE_ERROR(Test,Cure,Var)  = If 'Test' is false, try to 'Cure' the error
  292. */
  293.  
  294. #define ASSERT(Test)\
  295.         ((Test) ? TRUE :\
  296.          (fprintf (SEF, "Assertion \"%s\" failed in file %s at line %d\n",\
  297.           #Test, __FILE__, __LINE__), exit (0)))
  298.  
  299. #define WARN_ERROR(Test,Mesg,Name) (Test ?:  fprintf (SEF,Mesg,Name))
  300. #define STOP_ERROR(Test,Mesg,Name) (Test ?: (fprintf (SEF,Mesg,Name),exit(0)))
  301. #define CURE_ERROR(Test,Cure,Var)  (Test ?: (Cure) ((void *) Var))
  302.  
  303. #endif
  304.  
  305. /* ------------------------------------------------------------------------- */
  306.