home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 8
/
CDASC08.ISO
/
NEWS
/
RADIANCE
/
SRC
/
RT
/
SPHERE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-10-07
|
2KB
|
86 lines
/* Copyright (c) 1992 Regents of the University of California */
#ifndef lint
static char SCCSid[] = "@(#)sphere.c 2.2 10/24/92 LBL";
#endif
/*
* sphere.c - compute ray intersection with spheres.
*
* 8/19/85
*/
#include "ray.h"
#include "otypes.h"
o_sphere(so, r) /* compute intersection with sphere */
OBJREC *so;
register RAY *r;
{
double a, b, c; /* coefficients for quadratic equation */
double root[2]; /* quadratic roots */
int nroots;
double t;
register FLOAT *ap;
register int i;
if (so->oargs.nfargs != 4)
objerror(so, USER, "bad # arguments");
ap = so->oargs.farg;
if (ap[3] < -FTINY) {
objerror(so, WARNING, "negative radius");
so->otype = so->otype == OBJ_SPHERE ?
OBJ_BUBBLE : OBJ_SPHERE;
ap[3] = -ap[3];
} else if (ap[3] <= FTINY)
objerror(so, USER, "zero radius");
/*
* We compute the intersection by substituting into
* the surface equation for the sphere. The resulting
* quadratic equation in t is then solved for the
* smallest positive root, which is our point of
* intersection.
* Since the ray is normalized, a should always be
* one. We compute it here to prevent instability in the
* intersection calculation.
*/
/* compute quadratic coefficients */
a = b = c = 0.0;
for (i = 0; i < 3; i++) {
a += r->rdir[i]*r->rdir[i];
t = r->rorg[i] - ap[i];
b += 2.0*r->rdir[i]*t;
c += t*t;
}
c -= ap[3] * ap[3];
nroots = quadratic(root, a, b, c); /* solve quadratic */
for (i = 0; i < nroots; i++) /* get smallest positive */
if ((t = root[i]) > FTINY)
break;
if (i >= nroots)
return(0); /* no positive root */
if (t >= r->rot)
return(0); /* other is closer */
r->ro = so;
r->rot = t;
/* compute normal */
a = ap[3];
if (so->otype == OBJ_BUBBLE)
a = -a; /* reverse */
for (i = 0; i < 3; i++) {
r->rop[i] = r->rorg[i] + r->rdir[i]*t;
r->ron[i] = (r->rop[i] - ap[i]) / a;
}
r->rod = -DOT(r->rdir, r->ron);
r->rox = NULL;
return(1); /* hit */
}