--- ray/src/common/cone.c 1989/02/02 10:34:30 1.1 +++ ray/src/common/cone.c 2003/07/27 22:12:01 2.9 @@ -1,15 +1,12 @@ -/* Copyright (c) 1986 Regents of the University of California */ - #ifndef lint -static char SCCSid[] = "$SunId$ LBL"; +static const char RCSid[] = "$Id: cone.c,v 2.9 2003/07/27 22:12:01 schorsch Exp $"; #endif - /* * cone.c - routines for making cones - * - * 2/12/86 */ +#include "copyright.h" + #include "standard.h" #include "object.h" @@ -48,7 +45,7 @@ getcone(o, getxf) /* get cone structure */ register OBJREC *o; int getxf; { - double fabs(), sqrt(); + int sgn0, sgn1; register CONE *co; if ((co = (CONE *)o->os) == NULL) { @@ -59,36 +56,68 @@ int getxf; co->ca = o->oargs.farg; /* get radii */ - if (o->otype == OBJ_CYLINDER || o->otype == OBJ_TUBE) { + if ((o->otype == OBJ_CYLINDER) | (o->otype == OBJ_TUBE)) { if (o->oargs.nfargs != 7) goto argcerr; - if (co->ca[6] <= FTINY) + if (co->ca[6] < -FTINY) { + objerror(o, WARNING, "negative radius"); + o->otype = o->otype == OBJ_CYLINDER ? + OBJ_TUBE : OBJ_CYLINDER; + co->ca[6] = -co->ca[6]; + } else if (co->ca[6] <= FTINY) goto raderr; + co->p0 = 0; co->p1 = 3; co->r0 = co->r1 = 6; } else { if (o->oargs.nfargs != 8) goto argcerr; - if (co->ca[6] < 0.0 || co->ca[7] < 0.0) + if (co->ca[6] < -FTINY) sgn0 = -1; + else if (co->ca[6] > FTINY) sgn0 = 1; + else sgn0 = 0; + if (co->ca[7] < -FTINY) sgn1 = -1; + else if (co->ca[7] > FTINY) sgn1 = 1; + else sgn1 = 0; + if (sgn0+sgn1 == 0) goto raderr; - if (fabs(co->ca[7] - co->ca[6]) <= FTINY) - goto raderr; - co->r0 = 6; - co->r1 = 7; + if ((sgn0 < 0) | (sgn1 < 0)) { + objerror(o, o->otype==OBJ_RING?USER:WARNING, + "negative radii"); + o->otype = o->otype == OBJ_CONE ? + OBJ_CUP : OBJ_CONE; + } + co->ca[6] = co->ca[6]*sgn0; + co->ca[7] = co->ca[7]*sgn1; + if (co->ca[7] - co->ca[6] > FTINY) { + if (o->otype == OBJ_RING) + co->p0 = co->p1 = 0; + else { + co->p0 = 0; co->p1 = 3; + } + co->r0 = 6; co->r1 = 7; + } else if (co->ca[6] - co->ca[7] > FTINY) { + if (o->otype == OBJ_RING) + co->p0 = co->p1 = 0; + else { + co->p0 = 3; co->p1 = 0; + } + co->r0 = 7; co->r1 = 6; + } else { + if (o->otype == OBJ_RING) + goto raderr; + o->otype = o->otype == OBJ_CONE ? + OBJ_CYLINDER : OBJ_TUBE; + o->oargs.nfargs = 7; + co->p0 = 0; co->p1 = 3; + co->r0 = co->r1 = 6; + } } /* get axis orientation */ - co->p0 = 0; - if (o->otype == OBJ_RING) { - if (co->ca[6] > co->ca[7]) { /* make r0 smaller */ - co->r0 = 7; - co->r1 = 6; - } - co->p1 = 0; + if (o->otype == OBJ_RING) VCOPY(co->ad, o->oargs.farg+3); - } else { - co->p1 = 3; - co->ad[0] = co->ca[3] - co->ca[0]; - co->ad[1] = co->ca[4] - co->ca[1]; - co->ad[2] = co->ca[5] - co->ca[2]; + else { + co->ad[0] = CO_P1(co)[0] - CO_P0(co)[0]; + co->ad[1] = CO_P1(co)[1] - CO_P0(co)[1]; + co->ad[2] = CO_P1(co)[2] - CO_P0(co)[2]; } co->al = normalize(co->ad); if (co->al == 0.0) @@ -96,15 +125,15 @@ int getxf; /* compute axis and side lengths */ if (o->otype == OBJ_RING) { co->al = 0.0; - co->sl = co->ca[co->r1] - co->ca[co->r0]; - } else if (o->otype == OBJ_CONE || o->otype == OBJ_CUP) { + co->sl = CO_R1(co) - CO_R0(co); + } else if ((o->otype == OBJ_CONE) | (o->otype == OBJ_CUP)) { co->sl = co->ca[7] - co->ca[6]; co->sl = sqrt(co->sl*co->sl + co->al*co->al); - } else { /* OBJ_CYLINDER || OBJ_TUBE */ + } else { /* OBJ_CYLINDER or OBJ_TUBE */ co->sl = co->al; } co->tm = NULL; - (CONE *)o->os = co; + o->os = (char *)co; } if (getxf && co->tm == NULL) conexform(co); @@ -114,30 +143,34 @@ argcerr: objerror(o, USER, "bad # arguments"); raderr: objerror(o, USER, "illegal radii"); + return NULL; /* pro forma return */ } +void freecone(o) /* free memory associated with cone */ OBJREC *o; { register CONE *co = (CONE *)o->os; + if (co == NULL) + return; if (co->tm != NULL) - free((char *)co->tm); - free(o->os); + free((void *)co->tm); + free((void *)co); o->os = NULL; } +void conexform(co) /* get cone transformation matrix */ register CONE *co; { - double sqrt(), fabs(); - double m4[4][4]; + MAT4 m4; register double d; register int i; - co->tm = (double (*)[4])malloc(sizeof(m4)); + co->tm = (RREAL (*)[4])malloc(sizeof(MAT4)); if (co->tm == NULL) error(SYSTEM, "out of memory in conexform"); @@ -146,10 +179,10 @@ register CONE *co; if (co->r0 == co->r1) d = 0.0; else - d = co->ca[co->r0] / (co->ca[co->r1] - co->ca[co->r0]); + d = CO_R0(co) / (CO_R1(co) - CO_R0(co)); for (i = 0; i < 3; i++) - co->tm[3][i] = d*(co->ca[co->p1+i] - co->ca[co->p0+i]) - - co->ca[co->p0+i]; + co->tm[3][i] = d*(CO_P1(co)[i] - CO_P0(co)[i]) + - CO_P0(co)[i]; /* rotate to positive z-axis */ setident4(m4); @@ -173,10 +206,9 @@ register CONE *co; multmat4(co->tm, co->tm, m4); /* scale z-axis */ - setident4(m4); - if (co->p0 != co->p1 && co->r0 != co->r1) { - d = fabs(co->ca[co->r1] - co->ca[co->r0]); - m4[2][2] = d/co->al; + if ((co->p0 != co->p1) & (co->r0 != co->r1)) { + setident4(m4); + m4[2][2] = (CO_R1(co) - CO_R0(co)) / co->al; + multmat4(co->tm, co->tm, m4); } - multmat4(co->tm, co->tm, m4); }