home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / GRAPHICS / rayshade.lzh / sphere.c < prev    next >
Text File  |  1990-05-08  |  3KB  |  145 lines

  1. /*
  2.  * sphere.c
  3.  *
  4.  * Copyright (C) 1989, Craig E. Kolb
  5.  *
  6.  * This software may be freely copied, modified, and redistributed,
  7.  * provided that this copyright notice is preserved on all copies.
  8.  *
  9.  * There is no warranty or other guarantee of fitness for this software,
  10.  * it is provided solely .  Bug reports or fixes may be sent
  11.  * to the author, who may or may not act on them as he desires.
  12.  *
  13.  * You may not include this software in a program or other software product
  14.  * without supplying the source, or without informing the end-user that the
  15.  * source is available for no extra charge.
  16.  *
  17.  * If you modify this software, you should include a notice giving the
  18.  * name of the person performing the modification, the date of modification,
  19.  * and the reason for such modification.
  20.  *
  21.  * $Id: sphere.c,v 3.0.1.1 89/12/06 16:33:35 craig Exp $
  22.  *
  23.  * $Log:    sphere.c,v $
  24.  * Revision 3.0.1.1  89/12/06  16:33:35  craig
  25.  * patch2: Added calls to new error/warning routines.
  26.  * 
  27.  * Revision 3.0  89/10/27  02:06:04  craig
  28.  * Baseline for first official release.
  29.  * 
  30.  */
  31. #include <math.h>
  32. #include <stdio.h>
  33. #include "constants.h"
  34. #include "typedefs.h"
  35. #include "funcdefs.h"
  36.  
  37. /*
  38.  * Create & return reference to a sphere.
  39.  */
  40. Object *
  41. maksph(surf, r, pos)
  42. char    *surf;
  43. double r;
  44. Vector *pos;
  45. {
  46.     Sphere       *sphere;
  47.     Object *newobj;
  48.     Primitive *prim;
  49.  
  50.     if (r < EPSILON) {
  51.         yywarning("Degenerate sphere.\n");
  52.         return (Object *)0;
  53.     }
  54.  
  55.     prim = mallocprim();
  56.     newobj = new_object(NULL, SPHERE, (char *)prim, (Trans *)NULL);
  57.     prim->type = SPHERE;
  58.     prim->surf = find_surface(surf);
  59.     sphere = (Sphere *)Malloc(sizeof(Sphere));
  60.     prim->objpnt.p_sphere = sphere;
  61.     /*
  62.      * sphere->r really holds the square of the radius.
  63.      */
  64.     sphere->r = r*r;
  65.     sphere->x = pos->x;
  66.     sphere->y = pos->y;
  67.     sphere->z = pos->z;
  68.  
  69.     return newobj;
  70. }
  71.  
  72. /*
  73.  * Ray/sphere intersection test.
  74.  */
  75. double
  76. intsph(pos, ray, obj)
  77. register Vector           *pos, *ray;
  78. Primitive       *obj;
  79. {
  80.     Sphere *sph;
  81.     double xadj, yadj, zadj;
  82.     double          b, t, s;
  83.     extern unsigned long primtests[];
  84.  
  85.     primtests[SPHERE]++;
  86.     sph = obj->objpnt.p_sphere;
  87.     /*
  88.      * Translate ray origin to object space and negate everything.
  89.      * (Thus, we translate the sphere into ray space, which saves
  90.      * us a couple of negations below.)
  91.      */
  92.     xadj = sph->x - pos->x;
  93.     yadj = sph->y - pos->y;
  94.     zadj = sph->z - pos->z;
  95.  
  96.     /*
  97.      * Solve quadratic equiation.  Recall that sph->r is the square of r.
  98.      */
  99.     b = xadj * ray->x + yadj * ray->y + zadj * ray->z;
  100.     t = b * b - xadj * xadj - yadj * yadj - zadj * zadj + sph->r;
  101.     if (t < 0)
  102.         return 0.;
  103.     t = sqrt(t);
  104.     s = b - t;
  105.     if (s > EPSILON)
  106.         return s;
  107.     s = b + t;
  108.     if (s > EPSILON)
  109.         return s;
  110.     return 0.;
  111. }
  112.  
  113. nrmsph(pos, obj, nrm)
  114. Vector           *pos, *nrm;
  115. Primitive       *obj;
  116. {
  117.     /*
  118.      * Don't bother dividing by by sphere->r -- the normal will be
  119.      * normalized later.
  120.      */
  121.     nrm->x = (pos->x - obj->objpnt.p_sphere->x);
  122.     nrm->y = (pos->y - obj->objpnt.p_sphere->y);
  123.     nrm->z = (pos->z - obj->objpnt.p_sphere->z);
  124. }
  125.  
  126. sphextent(o, bounds)
  127. Primitive *o;
  128. double bounds[2][3];
  129. {
  130.     Sphere *s = o->objpnt.p_sphere;
  131.     double r;
  132.  
  133.     /*
  134.      * Could store both r*r and r, but sphextent is only
  135.      * called in preprocessing, so...
  136.      */
  137.     r = sqrt(s->r);
  138.     bounds[LOW][X] = s->x - r;
  139.     bounds[HIGH][X] = s->x + r;
  140.     bounds[LOW][Y] = s->y - r;
  141.     bounds[HIGH][Y] = s->y + r;
  142.     bounds[LOW][Z] = s->z - r;
  143.     bounds[HIGH][Z] = s->z + r;
  144. }
  145.