home *** CD-ROM | disk | FTP | other *** search
/ Mega Top 1 / os2_top1.zip / os2_top1 / APPS / RAYTRACE / RT / BIPLANE.C next >
C/C++ Source or Header  |  1994-05-22  |  6KB  |  267 lines

  1. /*
  2.  
  3. BIPLANE.C  Half-plane logic
  4.  
  5. */
  6.  
  7. /*...sincludes:0:*/
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <stddef.h>
  11. #include <malloc.h>
  12. #include <memory.h>
  13. #include <math.h>
  14. #include "standard.h"
  15. #include "rt.h"
  16. #include "vector.h"
  17. #include "sil.h"
  18. #define    _BIPLANE_
  19. #include "biplane.h"
  20.  
  21. /*...vrt\46\h:0:*/
  22. /*...vvector\46\h:0:*/
  23. /*...vsil\46\h:0:*/
  24. /*...vbiplane\46\h:0:*/
  25. /*...e*/
  26.  
  27. /*...screate_biplane      \45\ create any general biplane:0:*/
  28. BIPLANE    *create_biplane(double a, double b, double c, double d1, double d2)
  29.     {
  30.     BIPLANE    *biplane;
  31.  
  32.     if ( (biplane = malloc(sizeof(BIPLANE))) == NULL )
  33.         return NULL;
  34.  
  35.     biplane->a  = a;
  36.     biplane->b  = b;
  37.     biplane->c  = c;
  38.     biplane->d1 = d1;
  39.     biplane->d2 = d2;
  40.     return biplane;
  41.     }
  42. /*...e*/
  43. /*...screate_x_in_biplane \45\ create biplane solid for x1 \60\\61\ x \60\\61\ x2:0:*/
  44. BIPLANE    *create_x_in_biplane(double x1, double x2)
  45.     {
  46.     return create_biplane(1.0, 0.0, 0.0, -x1, -x2);
  47.     }
  48. /*...e*/
  49. /*...screate_y_in_biplane \45\ create biplane solid for y1 \60\\61\ y \60\\61\ y2:0:*/
  50. BIPLANE    *create_y_in_biplane(double y1, double y2)
  51.     {
  52.     return create_biplane(0.0, 1.0, 0.0, -y1, -y2);
  53.     }
  54. /*...e*/
  55. /*...screate_z_in_biplane \45\ create biplane solid for z1 \60\\61\ z \60\\61\ z2:0:*/
  56. BIPLANE    *create_z_in_biplane(double z1, double z2)
  57.     {
  58.     return create_biplane(0.0, 0.0, 1.0, -z1, -z2);
  59.     }
  60. /*...e*/
  61. /*...scopy_biplane        \45\ make a copy of a biplane:0:*/
  62. BIPLANE    *copy_biplane(BIPLANE *biplane)
  63.     {
  64.     BIPLANE    *copy;
  65.  
  66.     if ( (copy = malloc(sizeof(BIPLANE))) == NULL )
  67.         return NULL;
  68.  
  69.     memcpy(copy, biplane, sizeof(BIPLANE));
  70.     return copy;
  71.     }
  72. /*...e*/
  73. /*...sdestroy_biplane     \45\ destroy a biplane:0:*/
  74. void    destroy_biplane(BIPLANE *biplane)
  75.     {
  76.     free(biplane);
  77.     }
  78. /*...e*/
  79.  
  80. /*...strans_x_biplane     \45\ translate by amount in x direction:0:*/
  81. void    trans_x_biplane(BIPLANE *biplane, double t)
  82.     {
  83.     double at = biplane->a * t;
  84.     biplane->d1 -= at;
  85.     biplane->d2 -= at;
  86.     }
  87. /*...e*/
  88. /*...strans_y_biplane     \45\ translate by amount in y direction:0:*/
  89. void    trans_y_biplane(BIPLANE *biplane, double t)
  90.     {
  91.     double bt = biplane->b * t;
  92.     biplane->d1 -= bt;
  93.     biplane->d2 -= bt;
  94.     }
  95. /*...e*/
  96. /*...strans_z_biplane     \45\ translate by amount in z direction:0:*/
  97. void    trans_z_biplane(BIPLANE *biplane, double t)
  98.     {
  99.     double ct = biplane->c * t;
  100.     biplane->d1 -= ct;
  101.     biplane->d2 -= ct;
  102.     }
  103. /*...e*/
  104. /*...sscale_x_biplane     \45\ scale by factor in x direction:0:*/
  105. void    scale_x_biplane(BIPLANE *biplane, double factor)
  106.     {
  107.     biplane->a /= factor;
  108.     }
  109. /*...e*/
  110. /*...sscale_y_biplane     \45\ scale by factor in y direction:0:*/
  111. void    scale_y_biplane(BIPLANE *biplane, double factor)
  112.     {
  113.     biplane->b /= factor;
  114.     }
  115. /*...e*/
  116. /*...sscale_z_biplane     \45\ scale by factor in z direction:0:*/
  117. void    scale_z_biplane(BIPLANE *biplane, double factor)
  118.     {
  119.     biplane->c /= factor;
  120.     }
  121. /*...e*/
  122. /*...srot_x_biplane       \45\ rotate about x axis by given angle:0:*/
  123. void    rot_x_biplane(BIPLANE *biplane, double angle)
  124.     {
  125.     double    b  = biplane->b;
  126.     double    c  = biplane->c;
  127.     double    ca = cos(angle);
  128.     double    sa = sin(angle);
  129.  
  130.     biplane->b = b * ca - c * sa;
  131.     biplane->c = b * sa + c * ca;
  132.     }
  133. /*...e*/
  134. /*...srot_y_biplane       \45\ rotate about y axis by given angle:0:*/
  135. void    rot_y_biplane(BIPLANE *biplane, double angle)
  136.     {
  137.     double    c  = biplane->c;
  138.     double    a  = biplane->a;
  139.     double    ca = cos(angle);
  140.     double    sa = sin(angle);
  141.  
  142.     biplane->c = c * ca - a * sa;
  143.     biplane->a = c * sa + a * ca;
  144.     }
  145. /*...e*/
  146. /*...srot_z_biplane       \45\ rotate about z axis by given angle:0:*/
  147. void    rot_z_biplane(BIPLANE *biplane, double angle)
  148.     {
  149.     double    a  = biplane->a;
  150.     double    b  = biplane->b;
  151.     double    ca = cos(angle);
  152.     double    sa = sin(angle);
  153.  
  154.     biplane->a = a * ca - b * sa;
  155.     biplane->b = a * sa + b * ca;
  156.     }
  157. /*...e*/
  158.  
  159. /*...sisects_reqd_biplane \45\ max number of isects we will generate:0:*/
  160. int    isects_reqd_biplane(BIPLANE *biplane)
  161.     {
  162.     biplane=biplane; /* Suppress 'unref arg' compiler warning */
  163.  
  164.     return 2;
  165.     }
  166. /*...e*/
  167. /*...sintersect_biplane   \45\ determine intersection range of t for biplane:0:*/
  168. /*
  169.  
  170. Any point along the line we are interested in is of the form p + tq.
  171.                                  ~    ~
  172. Given:    ax+by+cz+d1 >0 and
  173.     ax+by+cz+d2<=0
  174.  
  175. Gives:    -d1<ax+by+cz<=d2
  176.  
  177. Subs:    x = x +tx        y = y +ty        z = z +tz
  178.          p   q             p   q             p   q
  179.  
  180. Gives:    (ax +by +cz )t + ax +by +cz +d = 0
  181.        q   q   q       p   p   p
  182.  
  183. */
  184.  
  185. #define    ZERO(x)        ( ((x)>=-1.0e-100) && ((x)<=1.0e-100) )
  186.  
  187. void    intersect_biplane(BIPLANE *biplane, VECTOR p, VECTOR q, SIL *sil)
  188.     {
  189.     double    a  = biplane->a;
  190.     double    b  = biplane->b;
  191.     double    c  = biplane->c;
  192.     double    d1 = biplane->d1;
  193.     double    d2 = biplane->d2;
  194.     double    coeff_of_t = a * q.x + b * q.y + c * q.z;
  195.     double    axbycz     = a * p.x + b * p.y + c * p.z;
  196.  
  197.     if ( ZERO(coeff_of_t) )
  198.         /* No intersection with solid surface */
  199.         {
  200.         if ( axbycz > -d1 && axbycz <= -d2 )
  201.             /* Completely in solid */
  202.             {
  203.             sil->n_sis            = 2;
  204.             sil->sis[0].t        = -INFINITE;
  205.             sil->sis[0].entering = TRUE;
  206.             sil->sis[1].t        = INFINITE;
  207.             sil->sis[1].entering = FALSE;
  208.             }
  209.         else
  210.             /* Completely out of solid */
  211.             sil->n_sis            = 0;
  212.         }
  213.     else
  214.         /* Intersects solid exactly twice */
  215.         {
  216.         double    t1 = - (axbycz + d1) / coeff_of_t;
  217.         double    t2 = - (axbycz + d2) / coeff_of_t;
  218.  
  219.         sil->n_sis            = 2;
  220.         sil->sis[0].entering = TRUE;
  221.         sil->sis[1].entering = FALSE;
  222.         if ( t1 < t2 )
  223.             {
  224.             sil->sis[0].t = t1;
  225.             sil->sis[1].t = t2;
  226.             }
  227.         else
  228.             {
  229.             sil->sis[0].t = t2;
  230.             sil->sis[1].t = t1;
  231.             }
  232.         }
  233.     }
  234. /*...e*/
  235. /*...snormal_to_biplane   \45\ find normal of surface at a given point:0:*/
  236. /*
  237. This is much like the simple plane case except that we know need to know the
  238. point of intersection in order to know which of the 2 half-plane surfaces were
  239. involved. We compute a d value, and if its closest to d2, then great, else
  240. the normal is the other way around.
  241. */
  242.  
  243. VECTOR    normal_to_biplane(BIPLANE *biplane, VECTOR p)
  244.     {
  245.     VECTOR    normal;
  246.     double    a = biplane->a;
  247.     double    b = biplane->b;
  248.     double    c = biplane->c;
  249.     double    d = - ( a * p.x + b * p.y + c * p.z );
  250.  
  251.     if ( fabs(d - biplane->d2) < fabs(d - biplane->d1) )
  252.         {
  253.         normal.x = a;
  254.         normal.y = b;
  255.         normal.z = c;
  256.         }
  257.     else
  258.         {
  259.         normal.x = -a;
  260.         normal.y = -b;
  261.         normal.z = -c;
  262.         }
  263.  
  264.     return normal;
  265.     }
  266. /*...e*/
  267.