home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
GRAPHICS
/
rayshade.lzh
/
superq.c
< prev
next >
Wrap
Text File
|
1990-05-08
|
3KB
|
160 lines
/*
* superq.c
*
* Slightly modified version of Kuchkuda's superquadric code.
*
* $Id: superq.c,v 3.0 89/10/27 02:06:05 craig Exp $
*
* $Log: superq.c,v $
* Revision 3.0 89/10/27 02:06:05 craig
* Baseline for first official release.
*
*/
#include <math.h>
#include "constants.h"
#include "typedefs.h"
#include "funcdefs.h"
#define ERRCONST 1.006
/*
* Create and return reference to a superquadric.
*/
Object *
maksup(surf, x, y, z, xs, ys, zs, power)
char *surf;
double x, y, z, xs, ys, zs, power;
{
double maxval;
Superq *super;
Primitive *prim;
Object *newobj;
prim = mallocprim();
prim->surf = find_surface(surf);
newobj = new_object(NULL, SUPERQ, (char *)prim, (Trans *)NULL);
prim->type = SUPERQ;
super = (Superq *) Malloc((unsigned)sizeof(Superq));
prim->objpnt.p_superq = super;
super->x = x;
super->y = y;
super->z = z;
super->bounds[LOW][X] = x - xs;
super->bounds[HIGH][X] = x + xs;
super->bounds[LOW][Y] = y - ys;
super->bounds[HIGH][Y] = y + ys;
super->bounds[LOW][Z] = z - zs;
super->bounds[HIGH][Z] = z + zs;
super->pow = power;
maxval = xs;
if (ys > maxval)
maxval = ys;
if (zs > maxval)
maxval = zs;
super->a = xs / maxval;
super->b = ys / maxval;
super->c = zs / maxval;
super->r = pow(maxval, power);
super->err = pow((ERRCONST * maxval), power) - super->r;
return newobj;
}
double
intsup(pos, ray, obj)
Vector *pos, *ray;
Primitive *obj;
{
double s, si, t;
double xadj, yadj, zadj;
double old, result, p;
Ray tmpray;
Superq *super;
extern unsigned long primtests[];
primtests[SUPERQ]++;
super = obj->objpnt.p_superq;
/* find box intersection */
if (OutOfBounds(pos, super->bounds)) {
tmpray.pos = *pos;
tmpray.dir = *ray;
s = IntBounds(&tmpray, super->bounds);
if (s <= 0.)
return 0;
}
else
s = 0.;
xadj = pos->x - super->x;
yadj = pos->y - super->y;
zadj = pos->z - super->z;
/* initial solution */
p = super->pow;
result = pow(fabs((xadj + ray->x * s) / super->a), p)
+ pow(fabs((yadj + ray->y * s) / super->b), p)
+ pow(fabs((zadj + ray->z * s) / super->c), p)
- super->r;
si = s;
s = s + 0.001;
/* iterative refinement */
while (result > super->err) {
old = result;
result = pow(fabs((xadj + ray->x * s) / super->a), p)
+ pow(fabs((yadj + ray->y * s) / super->b), p)
+ pow(fabs((zadj + ray->z * s) / super->c), p)
- super->r;
if (result >= old)
return (0.0);
t = (result * (s - si)) / (result - old);
si = s;
s -= t;
}
return (s);
}
nrmsup(pos, obj, nrm)
Vector *pos, *nrm;
Primitive *obj;
{
double k;
Superq *super;
super = obj->objpnt.p_superq;
nrm->x = (pos->x - super->x) / super->a;
nrm->y = (pos->y - super->y) / super->b;
nrm->z = (pos->z - super->z) / super->c;
k = super->pow - 1;
if (nrm->x > 0)
nrm->x = pow(nrm->x, k);
else
nrm->x = -pow(-nrm->x, k);
if (nrm->y > 0)
nrm->y = pow(nrm->y, k);
else
nrm->y = -pow(-nrm->y, k);
if (nrm->z > 0)
nrm->z = pow(nrm->z, k);
else
nrm->z = -pow(-nrm->z, k);
}
supextent(o, bounds)
Primitive *o;
double bounds[2][3];
{
Superq *s = o->objpnt.p_superq;
bounds[LOW][X] = s->bounds[LOW][X];
bounds[HIGH][X] = s->bounds[HIGH][X];
bounds[LOW][Y] = s->bounds[LOW][Y];
bounds[HIGH][Y] = s->bounds[HIGH][Y];
bounds[LOW][Z] = s->bounds[LOW][Z];
bounds[HIGH][Z] = s->bounds[HIGH][Z];
}