home *** CD-ROM | disk | FTP | other *** search
/ Virtual Reality Zone / VRZONE.ISO / mac / PC / PCGLOVE / GLOVE / OBJGLV.ZIP / SRC / DEMO4B / INT / INTTRIG.CPP < prev    next >
C/C++ Source or Header  |  1992-08-18  |  5KB  |  293 lines

  1. /* Routines for trignometry */
  2. /* assembly by Dave Stampe */
  3.  
  4. /* Copyright 1992 by Dave Stampe and Bernie Roehl.
  5.      May be freely used to write software for release into the public domain;
  6.      all commercial endeavours MUST contact Bernie Roehl and Dave Stampe
  7.      for permission to incorporate any part of this software into their
  8.      products!
  9.  */
  10.  
  11. /* Contact: broehl@sunee.waterloo.edu or dstampe@sunee.waterloo.edu */
  12.  
  13. #pragma inline
  14.  
  15.  
  16. /*************** TRIGNOMETRIC FUNCTIONS *****************/
  17.  
  18. #define XFSC 536870912   /* 2**29 for shifting xform coeffs to long */
  19.  
  20. extern long sintable[258];
  21. extern long atantable[258];    /* <3.29> args -> <16.16> angle */
  22.  
  23.  
  24. long isine(long angle)           /* returns <3.29> sine of <16.16> angle */
  25. {
  26.  long result;
  27.  
  28. /* return(XFSC * sin(3.14159/180*angle/65536.0));*/
  29.  
  30.  asm {
  31.     .386
  32.     mov    eax,angle
  33.     mov    edx,5B05B05Bh
  34.     imul    edx
  35.     shrd    eax,edx,29       /* convert so 90 deg -> 256 */
  36.     adc    eax,0              /* 2 upper bits = quadrant  */
  37.     mov    angle,eax          /* 16 lsb used to interp.   */
  38.      }
  39.  
  40.  asm {
  41.     mov    ebx,eax
  42.     mov    esi,eax
  43.     mov    edx,eax
  44.  
  45.     shr    ebx,14             /* 8 bit 2.84*degree index */
  46.     and    ebx,03FCh
  47.     test    esi,01000000h
  48.     jz    forward
  49.     not    edx
  50.     xor    ebx,03FCh
  51.      }
  52. forward:
  53.  asm {
  54.     mov    ecx,DWORD PTR ds:sintable[bx]
  55.     mov    eax,DWORD PTR ds:sintable+4[bx]  /* lookup this, next entry */
  56.     sub    eax,ecx
  57.  
  58.     and    edx,0000FFFFh       /* compute interp. factor */
  59.     mul     edx
  60.     shrd    eax,edx,16
  61.     adc    ecx,eax             /* add in */
  62.  
  63.     test    esi,02000000h
  64.     jz    positive
  65.     neg    ecx
  66.      }
  67. positive:
  68.  asm {
  69.     mov    result,ecx
  70.      }
  71.  return result;
  72. }
  73.  
  74.  
  75. long icosine(long angle)
  76. {
  77.  return isine(90*65536L + angle);
  78. }
  79.  
  80.  
  81. /************ INVERSE TRIG FUNCTIONS *************/
  82.  
  83. long arcsine(long x)      /* <3.29> args -> <16.16> angle */
  84. {                         /* have to use table in reverse */
  85.  int sign = 0;            /* because slope varies widely  */
  86.  long result;
  87.  long *stp = &sintable[0];
  88.  
  89.  if(x==0) return 0;
  90.  if(x<0)
  91.   {
  92.    sign++;
  93.    x = -x;
  94.   }
  95.  if(x>=XFSC)
  96.   {
  97.    result = 90*65536L;
  98.    goto ret90;
  99.   }
  100.  
  101.  asm {
  102.     push    si
  103.     push    di
  104.     push    dx
  105.     push    cx
  106.  
  107.     mov    bx,WORD PTR stp      /* fast binary search sine table */
  108.     xor    ecx,ecx
  109.     mov    eax,x
  110.     cmp    eax,[bx+512]
  111.     jb    b1
  112.     add    ebx,512
  113.     or    ecx,00800000h
  114.      }
  115. b1:
  116.  asm {
  117.     cmp    eax,[bx+256]
  118.     jb    b2
  119.     add    ebx,256
  120.     or    ecx,00400000h
  121.      }
  122. b2:
  123.  asm {
  124.     cmp    eax,[bx+128]
  125.     jb    b3
  126.     add    ebx,128
  127.     or    ecx,00200000h
  128.      }
  129. b3:
  130.  asm {
  131.     cmp    eax,[bx+64]
  132.     jb    b4
  133.     add    ebx,64
  134.     or    ecx,00100000h
  135.      }
  136. b4:
  137.  asm {
  138.     cmp    eax,[bx+32]
  139.     jb    b5
  140.     add    ebx,32
  141.     or    ecx,00080000h
  142.          }
  143. b5:
  144.  asm {
  145.     cmp    eax,[bx+16]
  146.     jb    b6
  147.     add    ebx,16
  148.     or    ecx,00040000h
  149.      }
  150. b6:
  151.  asm {
  152.     cmp    eax,[bx+8]
  153.     jb    b7
  154.     add    ebx,8
  155.     or    ecx,00020000h
  156.      }
  157. b7:
  158.  asm {
  159.     cmp    eax,[bx+4]
  160.     jb    b8
  161.     add    ebx,4
  162.     or    ecx,00010000h
  163.      }
  164. b8:
  165.  asm {
  166.     sub    eax,[bx]
  167.     je    nointerp
  168.     mov    esi,[bx+4]
  169.     sub    esi,[bx]
  170.     je    okinterp
  171.     cmp    eax,esi
  172.     jb    okinterp
  173.     add    ecx,00010000h
  174.     jmp    nointerp
  175.      }
  176. okinterp:
  177.  asm {
  178.     cdq
  179.     shld    edx,eax,16
  180.     shl    eax,16
  181.     idiv    esi
  182.     mov    cx,ax
  183.      }
  184. nointerp:
  185.  asm {
  186.     mov    eax,05A000000h    /* convert to <16.16> angle */
  187.     imul    ecx
  188.     mov    result,edx
  189.  
  190.     pop    cx
  191.     pop    dx
  192.     pop    di
  193.     pop    si
  194.      }
  195.  
  196. ret90:
  197.  return (sign) ? -result : result;
  198. }
  199.  
  200.  
  201. long arccosine(long x)
  202. {
  203.  return(90*65536L - arcsine(x));
  204. }
  205.  
  206.                          /* we can use a table for atan  */
  207.                    /* as slope is fairly constant  */
  208. long arctan2(long y, long x)
  209. {
  210.  long result;
  211.  int sx = 0;
  212.  int sy = 0;
  213.  int g45 = 0;
  214.  
  215.  if(x<0)           /* extract signs */
  216.   {
  217.    sx++;
  218.    x = -x;
  219.   }
  220.  if(y<0)           /* look for trivial solutions */
  221.   {
  222.    sy++;
  223.    y = -y;
  224.   }
  225.  if(x==0)
  226.   {
  227.    result = 90*65536L;
  228.    goto retconst;
  229.   }
  230.  if(y==0)
  231.   {
  232.    result = 0;
  233.    goto retconst;
  234.   }
  235.  
  236.  if(y>x)        /* confine to single octant */
  237.   {
  238.    g45++;
  239.    result = x;
  240.    x = y;
  241.    y = result;
  242.   }
  243.  
  244.  asm {
  245.     mov    edx,y
  246.     xor    eax,eax
  247.     mov    ebx,x
  248.     cmp    edx,ebx
  249.     jne    non45
  250.     mov    eax,02D0000h    /* 45 degrees */
  251.     mov    result,eax
  252.     jmp    retconst
  253.      }
  254. non45:
  255.  asm {
  256.     push    si
  257.     push    di
  258.  
  259.     shrd    eax,edx,8      /* shift so it will divide OK */
  260.     shr    edx,8
  261.     idiv    ebx            /* y/x << 24 */
  262.     mov    ebx,eax
  263.     shr    ebx,14         /* top 8 bits are index into table */
  264.     and    ebx,03FCh
  265.     mov    edi,DWORD PTR atantable[bx]
  266.     mov    esi,DWORD PTR atantable+4[bx]
  267.     sub    esi,edi
  268.     and    eax,0000FFFFh  /* bottom 16 bits interpolate */
  269.     mul    esi
  270.     shr    eax,16
  271.     add    eax,edi
  272.     mov    result,eax
  273.  
  274.     pop    di
  275.     pop    si
  276.      }
  277.  
  278.  if(g45) result = 90*65536L - result;
  279.  
  280. retconst:
  281.  if(sx)
  282.   {
  283.    if(sy) return result - 180*65536L;
  284.    else   return 180*65536L - result;
  285.   }
  286.  else
  287.   {
  288.    if(sy) return -result;
  289.    else   return  result;
  290.   }
  291. }
  292.  
  293.