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