home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / raytrace / radiance / simplerd.lha / simplerad / FinalFTP / Light / raysphere.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-21  |  2.4 KB  |  80 lines

  1. /**********************************************************************/
  2. /* raysphere.c                                                        */
  3. /*                                                                    */
  4. /* Ray / sphere intersection routines                                 */
  5. /* Modified from Optik v(1.2e) (C) 1987 John Amanatides & Andrew Woo  */
  6. /*                                                                    */
  7. /* Copyright (C) 1992, Bernard Kwok                                   */
  8. /* All rights reserved.                                               */
  9. /* Revision 1.0                                                       */
  10. /* May, 1992                                                          */
  11. /**********************************************************************/
  12. #include <stdio.h>
  13. #include <math.h>
  14. #include "geo.h"
  15. #include "struct.h"
  16. #include "io.h"
  17. #include "ray.h"
  18.  
  19. extern RayStats_Type RayStats;
  20. extern OptionType Option;
  21.  
  22. /**********************************************************************/
  23. /* Intersect a ray with a unit sphere */
  24. /**********************************************************************/
  25. RaySphere(ray, hit, optr)
  26.      register Ray *ray;
  27.      register HitData *hit;
  28.      register Objectt *optr;
  29. {
  30.   double a,b,c,r1,r2,t,discrim;
  31.  
  32.   RayStats.raySphere++;
  33.   if (Option.debug)
  34.     printf("\t\tRay-Sphere: (%g,%g,%g) > (%g,%g,%g)\n",
  35.        ray->origin.x, ray->origin.y, ray->origin.z, 
  36.        ray->dir.x, ray->dir.y, ray->dir.z);
  37.   
  38.   /* Find a,b,c of at**2 + bt + c */
  39.   a= dot(&ray->dir, &ray->dir);
  40.   b= 2.0 * dot(&ray->origin, &ray->dir);
  41.   c= dot(&ray->origin, &ray->origin) - 1.0;
  42.   
  43.   /* Calculate discriminant */
  44.   discrim= b*b -4.0*a*c;
  45.   if (discrim <= 0.)
  46.     return;
  47.   
  48.   /* Find closest intersection (also watch for stability)  */
  49.   if (b < 0.0) {
  50.     r2= (-b + sqrt(discrim)) / (2.0 * a);
  51.     r1= c / (a * r2);
  52.   } else { 
  53.     r1= (-b -sqrt(discrim)) / (2.0 * a);
  54.     r2= c / (a * r1);
  55.   }
  56.   if (r1 <= MIN_DISTANCE)    /* for round-off errors */
  57.     if (r2 <= MIN_DISTANCE)
  58.       return;
  59.     else
  60.       t= r2;
  61.   else
  62.     t=r1;
  63.   
  64.   if (hit->distance <= t)
  65.     return;
  66.   
  67.   /* Store hit information */
  68.   RayStats.intSphere++;
  69.   if (Option.visibility == FORM_FACTOR)
  70.     ray->visible = 0.0;
  71.   Store_HitInter(hit, optr, 
  72.          (ray->origin.x + t * ray->dir.x),
  73.          (ray->origin.y + t * ray->dir.y),
  74.          (ray->origin.z + t * ray->dir.z));
  75.   if (!ray->shadow) {
  76.     hit->normal= hit->intersect;
  77.     hit->texture= hit->intersect;
  78.   }
  79. }
  80.