home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 505a.lha / GrapicsGems / FixedTrig.c < prev    next >
Text File  |  1991-05-01  |  2KB  |  71 lines

  1. /* 
  2. Fixed-Point Trigonometry with CORDIC Iterations
  3. by Ken Turkowski
  4. from "Graphics Gems", Academic Press, 1990
  5. */
  6.  
  7. #define COSCALE 0x22c2dd1c /* 0.271572 */
  8. #define QUARTER ((int)(3.141592654 / 2.0 * (1 << 28)))
  9. static long arctantab[32] = {  /* MS 4 integral bits for radians */
  10.     297197971, 210828714, 124459457, 65760959, 33381290, 16755422,
  11.     8385879, 4193963, 2097109, 1048571, 524287, 262144, 131072,
  12.     65536, 32768, 16384, 8192, 4096, 2048, 1024, 512, 256, 128, 64,
  13.     32, 16, 8, 4, 2, 1, 0, 0,
  14. };
  15.  
  16. CordicRotate(px, py, theta)
  17. long *px, *py;
  18. register long theta;    /* Assume that abs(theta) <= pi */
  19. {
  20.     register int i;
  21.     register long x = *px, y = *py, xtemp;
  22.     register long *arctanptr = arctantab;
  23.  
  24.     /* The -1 may need to be pulled out and done as a left shift */
  25.     for (i = -1; i <= 28; i++) {
  26.         if (theta < 0) {
  27.             xtemp = x + (y >> i);
  28.             y     = y - (x >> i);
  29.             x = xtemp;
  30.             theta += *arctanptr++;
  31.         } else {
  32.             xtemp = x - (y >> i);    
  33.             y     = y + (x >> i);
  34.             x = xtemp;    
  35.             theta -= *arctanptr++;
  36.         }
  37.     }
  38.  
  39.     *px = frmul(x, COSCALE); /* Compensate for CORDIC enlargement */
  40.     *py = frmul(y, COSCALE); /* frmul(a,b)=(a*b)>>31, high part  */
  41.                  /* of 64-bit product */
  42. }
  43.  
  44.  
  45.  
  46.  
  47. CordicPolarize(argx, argy)
  48. long *argx, *argy;    /* We assume these are already in the */
  49.                     /*  right half plane */
  50. {
  51.     register long theta, yi, i;
  52.     register long x = *argx, y = *argy;
  53.     register long *arctanptr = arctantab;
  54.     for (i = -1; i <= 28; i++) {
  55.         if (y < 0) {        /* Rotate positive */
  56.             yi = y + (x >> i);
  57.             x  = x - (y >> i);
  58.             y  = yi;
  59.             theta -= *arctanptr++;
  60.         } else {         /* Rotate negative */
  61.             yi = y - (x >> i);
  62.             x  = x + (y >> i);
  63.             y  = yi;
  64.             theta += *arctanptr++;
  65.         }
  66.     }
  67.  
  68.     *argx = frmul(x, COSCALE);
  69.     *argy = theta;
  70. }
  71.