home *** CD-ROM | disk | FTP | other *** search
/ RISC DISC 3 / RISC_DISC_3.iso / resources / etexts / gems / gemsiii / intell.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-12-14  |  3.1 KB  |  96 lines

  1. #include    <math.h>
  2. #include    "GraphicsGems.h"
  3.  
  4. /* ----    intell - Intersect a ray with an ellipsoid. -------------------    */
  5. /*                                    */
  6. /*                                    */
  7. /*    Description:                            */
  8. /*        Intell determines the intersection of a ray with an        */
  9. /*        ellipsoid.                            */
  10. /*                                    */
  11. /*    On entry:                            */
  12. /*        raybase = The coordinate defining the base of the        */
  13. /*              intersecting ray.                    */
  14. /*        raycos  = The direction cosines of the above ray.        */
  15. /*        center  = The location of the center of the ellispoid.    */
  16. /*        radius  = The radius of a bounding sphere.            */
  17. /*        Q       = A 4x4 coefficient matrix representing the quadric    */
  18. /*              surface.                        */
  19. /*                                    */
  20. /*    On return:                            */
  21. /*        rin     = The entering distance of the intersection.    */
  22. /*        rout    = The leaving  distance of the intersection.    */
  23. /*                                    */
  24. /*    Returns:  True if the ray intersects the ellipsoid.        */
  25. /*                                    */
  26. /* --------------------------------------------------------------------    */
  27.  
  28.  
  29. boolean    intell    (raybase,raycos,center,radius,Q,rin,rout)
  30.  
  31.     Point3    raybase;        /* Base of the intersection ray    */
  32.     Vector3    raycos;            /* Direction cosines of the ray    */
  33.     Vector3    center;            /* Base point for the quadric    */
  34.     double    radius;            /* Bounding radius        */
  35.     Matrix4    Q;            /* Quadric coefficient matrix    */
  36.     double    *rin;            /* Entering distance        */
  37.     double    *rout;            /* Leaving  distance        */
  38.  
  39. {
  40.     boolean    hit;            /* True if ray intersects quad.    */
  41.     double    qa, qb, qc, qd, qe,    /* Coefficient matrix terms    */
  42.         qf, qg, qh, qi, qj;
  43.     double    k2, k1, k0;        /* Quadric coefficients        */
  44.     double    disc;
  45.     Vector3    D;            /* Ray base to ellipsoid base    */
  46.     double    d;            /* Shortest distance between    */
  47.                     /* ray and ellipsoid        */
  48.  
  49.  
  50. /*    Compute the minimal distance between the ray and the center    */
  51. /*    of the ellipsoid.                        */
  52.  
  53.     V3Sub (¢er,&raybase,&D);
  54.     d   = V3Length (&D);
  55.     V3Normalize (&D);
  56.     d   = d * sqrt (1. - V3Dot(&D,&raycos));
  57.     hit  = (d <= radius);
  58.   
  59.     if  (!hit) return (hit);        /* If outside of sphere    */
  60.  
  61.  
  62.     qa = Q.element[0][0];
  63.     qb = Q.element[0][1] + Q.element[1][0];
  64.     qc = Q.element[0][2] + Q.element[2][0];
  65.     qd = Q.element[0][3] + Q.element[3][0];
  66.     qe = Q.element[1][1];
  67.     qf = Q.element[1][2] + Q.element[2][1];
  68.     qg = Q.element[1][3] + Q.element[3][1];
  69.     qh = Q.element[2][2];
  70.     qi = Q.element[2][3] + Q.element[3][2];
  71.     qj = Q.element[3][3];
  72.  
  73.     k2 = raycos.x * (raycos.x*qa + raycos.y*qb) +
  74.          raycos.y * (raycos.y*qe + raycos.z*qf) +
  75.          raycos.z * (raycos.z*qh + raycos.z*qc);
  76.     k1 = raycos.x * ((raybase.x*2.*qa + raybase.y*qb + raybase.z*qc) + qd) +
  77.          raycos.y * ((raybase.x*qb + raybase.y*2.*qe + raybase.z*qf) + qg) +
  78.          raycos.z * ((raybase.x*qc + raybase.y*qg + raybase.z*2.*qh) + qi);
  79.     k0 = raybase.x * (raybase.x*qa + raybase.y*qb + raybase.z*qc + qd) +
  80.          raybase.y * (               raybase.y*qe + raybase.z*qf + qg) +
  81.          raybase.z * (                              raybase.z*qh + qi) +
  82.          qj;
  83.  
  84.     disc = k1*k1 - 4.*k2*k0;
  85.   
  86.     hit  = (disc >= 0.0);
  87.  
  88.     if  (hit) {                 /* If ray hits quadric    */
  89.         disc  =  sqrt(disc);
  90.         *rin  = (-k1 - disc) / (2.*k2);    /*    entering distance    */
  91.         *rout = (-k1 + disc) / (2.*k2);    /*    leaving distance    */
  92.     }
  93.   
  94.     return (hit);
  95. }
  96.