home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / graphic / csg_rt / sil.c < prev    next >
C/C++ Source or Header  |  1992-07-28  |  5KB  |  195 lines

  1. /*
  2.  
  3. SIL.C  Simple intersection lists
  4.  
  5. */
  6.  
  7. /*...sincludes:0:*/
  8. #include <stdlib.h>
  9. #include <stddef.h>
  10. #include <memory.h>
  11. #include <math.h>
  12. #include "standard.h"
  13. #include "rt.h"
  14. #include "vector.h"
  15. #define    _SIL_
  16. #include "sil.h"
  17.  
  18. /*...vrt\46\h:0:*/
  19. /*...vvector\46\h:0:*/
  20. /*...vsil\46\h:0:*/
  21. /*...e*/
  22.  
  23. #define    ZERO(x)        ( ((x)>=-1.0e-100) && ((x)<=1.0e-100) )
  24.  
  25. /*...st_a_bit_later:0:*/
  26. static double t_a_bit_later(double t)
  27.     {
  28.     return ( t + 100.0 );
  29.     }
  30. /*...e*/
  31. /*...st_a_bit_before:0:*/
  32. static double t_a_bit_before(double t)
  33.     {
  34.     return ( t - 100.0 );
  35.     }
  36. /*...e*/
  37.  
  38. /*...sintersect_linear_t:0:*/
  39. void    intersect_linear_t(
  40.     double coeff_of_t, double constant_term,
  41.     VECTOR p, VECTOR q,
  42.     void *shapeinfo, double (*value_of_shape)(void *shapeinfo, VECTOR v),
  43.     SIL *sil
  44.     )
  45.     {
  46.     if ( ZERO(coeff_of_t) )
  47.         /* No intersection with solid surface */
  48.         {
  49.         if ( (*value_of_shape)(shapeinfo, p) <= 0.0 )
  50.             /* Completely in solid */
  51.             {
  52.             sil -> n_sis            = 2;
  53.             sil -> sis [0].t        = -INFINITE;
  54.             sil -> sis [0].entering = TRUE;
  55.             sil -> sis [1].t        = INFINITE;
  56.             sil -> sis [1].entering = FALSE;
  57.             }
  58.         else
  59.             /* Completely out of solid */
  60.             sil -> n_sis            = 0;
  61.         }
  62.     else
  63.         /* Intersects solid exactly once */
  64.         {
  65.         double    t = - constant_term / coeff_of_t;
  66.  
  67.         sil -> n_sis            = 2;
  68.         sil -> sis [0].entering = TRUE;
  69.         sil -> sis [1].entering = FALSE;
  70.         if ( (*value_of_shape)(shapeinfo, t_along_pq(p, q, t_a_bit_later(t))) <= 0.0 )
  71.             /* Entering solid */
  72.             {
  73.             sil -> sis [0].t = t;
  74.             sil -> sis [1].t = INFINITE;
  75.             }
  76.         else
  77.             /* Leaving solid */
  78.             {
  79.             sil -> sis [0].t = -INFINITE;
  80.             sil -> sis [1].t = t;
  81.             }
  82.         }
  83.     }
  84. /*...e*/
  85. /*...sintersect_quadratic_t:0:*/
  86. void    intersect_quadratic_t(
  87.     double qa, double qb, double qc,
  88.     VECTOR p, VECTOR q,
  89.     void *shapeinfo, double (*value_of_shape)(void *shapeinfo, VECTOR v),
  90.     SIL *sil
  91.     )
  92.     {
  93.     double    qs;
  94.  
  95.     if ( ZERO(qa) )
  96. /*...sdo linear case:16:*/
  97. intersect_linear_t(qb, qc, p, q, shapeinfo, value_of_shape, sil);
  98. /*...e*/
  99.     else if ( (qs = qb*qb - 4.0*qa*qc) < 0.0 )
  100. /*...sno real roots:16:*/
  101. /* No real roots => no intersections, all solid or all empty */
  102. {
  103. if ( (*value_of_shape)(shapeinfo, p) <= 0.0 )
  104.     {
  105.     sil -> n_sis            = 2;
  106.     sil -> sis [0].t        = -INFINITE;
  107.     sil -> sis [0].entering = TRUE;
  108.     sil -> sis [1].t        = INFINITE;
  109.     sil -> sis [1].entering = FALSE;
  110.     }
  111. else
  112.     sil -> n_sis = 0;
  113. }
  114. /*...e*/
  115.     else if ( ZERO(qs) )
  116. /*...sone double root:16:*/
  117. {
  118. double    t = -qb / (qa + qa);
  119. BOOLEAN from_inside = ( (*value_of_shape)(shapeinfo, t_along_pq(p, q, t_a_bit_before(t))) <= 0.0 );
  120. BOOLEAN to_inside   = ( (*value_of_shape)(shapeinfo, t_along_pq(p, q, t_a_bit_later(t))) <= 0.0 );
  121.  
  122. #define    DUAL_SWITCH(f,t)    (((f)<<1)+(t))
  123.  
  124. switch ( DUAL_SWITCH(from_inside, to_inside) )
  125.     {
  126.     case DUAL_SWITCH(FALSE, FALSE):        /* Grazing surface */
  127.         sil -> n_sis            = 0;
  128.         break;
  129.     case DUAL_SWITCH(FALSE,  TRUE):        /* Entering solid area */
  130.         sil -> n_sis            = 2;
  131.         sil -> sis [0].t        = t;
  132.         sil -> sis [0].entering = TRUE;
  133.         sil -> sis [1].t        = INFINITE;
  134.         sil -> sis [1].entering = FALSE;
  135.         break;
  136.     case DUAL_SWITCH( TRUE, FALSE):        /* Leaving solid area */
  137.         sil -> n_sis            = 2;
  138.         sil -> sis [0].t        = -INFINITE;
  139.         sil -> sis [0].entering = TRUE;
  140.         sil -> sis [1].t        = t;
  141.         sil -> sis [1].entering = FALSE;
  142.         break;
  143.     case DUAL_SWITCH( TRUE,  TRUE):        /* Never left solid area */
  144.         sil -> n_sis            = 2;
  145.         sil -> sis [0].t        = -INFINITE;
  146.         sil -> sis [0].entering = TRUE;
  147.         sil -> sis [1].t        = INFINITE;
  148.         sil -> sis [1].entering = FALSE;
  149.         break;
  150.     }
  151. }
  152. /*...e*/
  153.     else
  154. /*...stwo roots:16:*/
  155. {
  156. double    rooted = sqrt(qs);
  157. double    t1 = (-qb - rooted) / (qa + qa);
  158. double    t2 = (-qb + rooted) / (qa + qa);
  159.  
  160. if ( t1 > t2 )
  161.     /* Ensure t1 is lower than t2 */
  162.     {
  163.     double    t = t1;
  164.  
  165.     t1 = t2;
  166.     t2 = t;
  167.     }
  168.  
  169. if ( (*value_of_shape)(shapeinfo, t_along_pq(p, q, (t1 + t2) * 0.5)) <= 0.0 )
  170.     /* Middle part is the solid part */
  171.     {
  172.     sil -> n_sis            = 2;
  173.     sil -> sis [0].t        = t1;
  174.     sil -> sis [0].entering = TRUE;
  175.     sil -> sis [1].t        = t2;
  176.     sil -> sis [1].entering = FALSE;
  177.     }
  178. else
  179.     /* Regions before and after middle part are the solid parts */
  180.     {
  181.     sil -> n_sis            = 4;
  182.     sil -> sis [0].t        = -INFINITE;
  183.     sil -> sis [0].entering = TRUE;
  184.     sil -> sis [1].t        = t1;
  185.     sil -> sis [1].entering = FALSE;
  186.     sil -> sis [2].t        = t2;
  187.     sil -> sis [2].entering = TRUE;
  188.     sil -> sis [3].t        = INFINITE;
  189.     sil -> sis [3].entering = FALSE;
  190.     }
  191. }
  192. /*...e*/
  193.     }
  194. /*...e*/
  195.