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 >
Wrap
Text File
|
1990-05-08
|
3KB
|
145 lines
/*
* sphere.c
*
* Copyright (C) 1989, Craig E. Kolb
*
* This software may be freely copied, modified, and redistributed,
* provided that this copyright notice is preserved on all copies.
*
* There is no warranty or other guarantee of fitness for this software,
* it is provided solely . Bug reports or fixes may be sent
* to the author, who may or may not act on them as he desires.
*
* You may not include this software in a program or other software product
* without supplying the source, or without informing the end-user that the
* source is available for no extra charge.
*
* If you modify this software, you should include a notice giving the
* name of the person performing the modification, the date of modification,
* and the reason for such modification.
*
* $Id: sphere.c,v 3.0.1.1 89/12/06 16:33:35 craig Exp $
*
* $Log: sphere.c,v $
* Revision 3.0.1.1 89/12/06 16:33:35 craig
* patch2: Added calls to new error/warning routines.
*
* Revision 3.0 89/10/27 02:06:04 craig
* Baseline for first official release.
*
*/
#include <math.h>
#include <stdio.h>
#include "constants.h"
#include "typedefs.h"
#include "funcdefs.h"
/*
* Create & return reference to a sphere.
*/
Object *
maksph(surf, r, pos)
char *surf;
double r;
Vector *pos;
{
Sphere *sphere;
Object *newobj;
Primitive *prim;
if (r < EPSILON) {
yywarning("Degenerate sphere.\n");
return (Object *)0;
}
prim = mallocprim();
newobj = new_object(NULL, SPHERE, (char *)prim, (Trans *)NULL);
prim->type = SPHERE;
prim->surf = find_surface(surf);
sphere = (Sphere *)Malloc(sizeof(Sphere));
prim->objpnt.p_sphere = sphere;
/*
* sphere->r really holds the square of the radius.
*/
sphere->r = r*r;
sphere->x = pos->x;
sphere->y = pos->y;
sphere->z = pos->z;
return newobj;
}
/*
* Ray/sphere intersection test.
*/
double
intsph(pos, ray, obj)
register Vector *pos, *ray;
Primitive *obj;
{
Sphere *sph;
double xadj, yadj, zadj;
double b, t, s;
extern unsigned long primtests[];
primtests[SPHERE]++;
sph = obj->objpnt.p_sphere;
/*
* Translate ray origin to object space and negate everything.
* (Thus, we translate the sphere into ray space, which saves
* us a couple of negations below.)
*/
xadj = sph->x - pos->x;
yadj = sph->y - pos->y;
zadj = sph->z - pos->z;
/*
* Solve quadratic equiation. Recall that sph->r is the square of r.
*/
b = xadj * ray->x + yadj * ray->y + zadj * ray->z;
t = b * b - xadj * xadj - yadj * yadj - zadj * zadj + sph->r;
if (t < 0)
return 0.;
t = sqrt(t);
s = b - t;
if (s > EPSILON)
return s;
s = b + t;
if (s > EPSILON)
return s;
return 0.;
}
nrmsph(pos, obj, nrm)
Vector *pos, *nrm;
Primitive *obj;
{
/*
* Don't bother dividing by by sphere->r -- the normal will be
* normalized later.
*/
nrm->x = (pos->x - obj->objpnt.p_sphere->x);
nrm->y = (pos->y - obj->objpnt.p_sphere->y);
nrm->z = (pos->z - obj->objpnt.p_sphere->z);
}
sphextent(o, bounds)
Primitive *o;
double bounds[2][3];
{
Sphere *s = o->objpnt.p_sphere;
double r;
/*
* Could store both r*r and r, but sphextent is only
* called in preprocessing, so...
*/
r = sqrt(s->r);
bounds[LOW][X] = s->x - r;
bounds[HIGH][X] = s->x + r;
bounds[LOW][Y] = s->y - r;
bounds[HIGH][Y] = s->y + r;
bounds[LOW][Z] = s->z - r;
bounds[HIGH][Z] = s->z + r;
}