ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/cone.c
Revision: 2.3
Committed: Fri Oct 2 16:01:06 1992 UTC (31 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.2: +0 -2 lines
Log Message:
Removed problematic math function declarations

File Contents

# Content
1 /* Copyright (c) 1992 Regents of the University of California */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ LBL";
5 #endif
6
7 /*
8 * cone.c - routines for making cones
9 *
10 * 2/12/86
11 */
12
13 #include "standard.h"
14
15 #include "object.h"
16
17 #include "otypes.h"
18
19 #include "cone.h"
20
21 /*
22 * In general, a cone may be any one of a cone, a cylinder, a ring,
23 * a cup (inverted cone), or a tube (inverted cylinder).
24 * Most cones are specified with a starting point and radius and
25 * an ending point and radius. In the cases of a cylinder or tube,
26 * only one radius is needed. In the case of a ring, a normal direction
27 * is specified instead of a second endpoint.
28 *
29 * mtype (cone|cup) name
30 * 0
31 * 0
32 * 8 P0x P0y P0z P1x P1y P1z R0 R1
33 *
34 * mtype (cylinder|tube) name
35 * 0
36 * 0
37 * 7 P0x P0y P0z P1x P1y P1z R
38 *
39 * mtype ring name
40 * 0
41 * 0
42 * 8 Px Py Pz Nx Ny Nz R0 R1
43 */
44
45
46 CONE *
47 getcone(o, getxf) /* get cone structure */
48 register OBJREC *o;
49 int getxf;
50 {
51 int sgn0, sgn1;
52 register CONE *co;
53
54 if ((co = (CONE *)o->os) == NULL) {
55
56 co = (CONE *)malloc(sizeof(CONE));
57 if (co == NULL)
58 error(SYSTEM, "out of memory in makecone");
59
60 co->ca = o->oargs.farg;
61 /* get radii */
62 if (o->otype == OBJ_CYLINDER | o->otype == OBJ_TUBE) {
63 if (o->oargs.nfargs != 7)
64 goto argcerr;
65 if (co->ca[6] < -FTINY) {
66 objerror(o, WARNING, "negative radius");
67 o->otype = o->otype == OBJ_CYLINDER ?
68 OBJ_TUBE : OBJ_CYLINDER;
69 co->ca[6] = -co->ca[6];
70 } else if (co->ca[6] <= FTINY)
71 goto raderr;
72 co->p0 = 0; co->p1 = 3;
73 co->r0 = co->r1 = 6;
74 } else {
75 if (o->oargs.nfargs != 8)
76 goto argcerr;
77 if (co->ca[6] < -FTINY) sgn0 = -1;
78 else if (co->ca[6] > FTINY) sgn0 = 1;
79 else sgn0 = 0;
80 if (co->ca[7] < -FTINY) sgn1 = -1;
81 else if (co->ca[7] > FTINY) sgn1 = 1;
82 else sgn1 = 0;
83 if (sgn0+sgn1 == 0)
84 goto raderr;
85 if (sgn0 < 0 | sgn1 < 0) {
86 objerror(o, o->otype==OBJ_RING?USER:WARNING,
87 "negative radii");
88 o->otype = o->otype == OBJ_CONE ?
89 OBJ_CUP : OBJ_CONE;
90 }
91 co->ca[6] = co->ca[6]*sgn0;
92 co->ca[7] = co->ca[7]*sgn1;
93 if (co->ca[7] - co->ca[6] > FTINY) {
94 if (o->otype == OBJ_RING)
95 co->p0 = co->p1 = 0;
96 else {
97 co->p0 = 0; co->p1 = 3;
98 }
99 co->r0 = 6; co->r1 = 7;
100 } else if (co->ca[6] - co->ca[7] > FTINY) {
101 if (o->otype == OBJ_RING)
102 co->p0 = co->p1 = 0;
103 else {
104 co->p0 = 3; co->p1 = 0;
105 }
106 co->r0 = 7; co->r1 = 6;
107 } else {
108 if (o->otype == OBJ_RING)
109 goto raderr;
110 o->otype = o->otype == OBJ_CONE ?
111 OBJ_CYLINDER : OBJ_TUBE;
112 o->oargs.nfargs = 7;
113 co->p0 = 0; co->p1 = 3;
114 co->r0 = co->r1 = 6;
115 }
116 }
117 /* get axis orientation */
118 if (o->otype == OBJ_RING)
119 VCOPY(co->ad, o->oargs.farg+3);
120 else {
121 co->ad[0] = CO_P1(co)[0] - CO_P0(co)[0];
122 co->ad[1] = CO_P1(co)[1] - CO_P0(co)[1];
123 co->ad[2] = CO_P1(co)[2] - CO_P0(co)[2];
124 }
125 co->al = normalize(co->ad);
126 if (co->al == 0.0)
127 objerror(o, USER, "zero orientation");
128 /* compute axis and side lengths */
129 if (o->otype == OBJ_RING) {
130 co->al = 0.0;
131 co->sl = CO_R1(co) - CO_R0(co);
132 } else if (o->otype == OBJ_CONE | o->otype == OBJ_CUP) {
133 co->sl = co->ca[7] - co->ca[6];
134 co->sl = sqrt(co->sl*co->sl + co->al*co->al);
135 } else { /* OBJ_CYLINDER or OBJ_TUBE */
136 co->sl = co->al;
137 }
138 co->tm = NULL;
139 o->os = (char *)co;
140 }
141 if (getxf && co->tm == NULL)
142 conexform(co);
143 return(co);
144
145 argcerr:
146 objerror(o, USER, "bad # arguments");
147 raderr:
148 objerror(o, USER, "illegal radii");
149 }
150
151
152 freecone(o) /* free memory associated with cone */
153 OBJREC *o;
154 {
155 register CONE *co = (CONE *)o->os;
156
157 if (o->os == NULL)
158 return;
159 if (co->tm != NULL)
160 free((char *)co->tm);
161 free(o->os);
162 o->os = NULL;
163 }
164
165
166 conexform(co) /* get cone transformation matrix */
167 register CONE *co;
168 {
169 MAT4 m4;
170 register double d;
171 register int i;
172
173 co->tm = (FLOAT (*)[4])malloc(sizeof(MAT4));
174 if (co->tm == NULL)
175 error(SYSTEM, "out of memory in conexform");
176
177 /* translate to origin */
178 setident4(co->tm);
179 if (co->r0 == co->r1)
180 d = 0.0;
181 else
182 d = CO_R0(co) / (CO_R1(co) - CO_R0(co));
183 for (i = 0; i < 3; i++)
184 co->tm[3][i] = d*(CO_P1(co)[i] - CO_P0(co)[i])
185 - CO_P0(co)[i];
186
187 /* rotate to positive z-axis */
188 setident4(m4);
189 d = co->ad[1]*co->ad[1] + co->ad[2]*co->ad[2];
190 if (d <= FTINY*FTINY) {
191 m4[0][0] = 0.0;
192 m4[0][2] = co->ad[0];
193 m4[2][0] = -co->ad[0];
194 m4[2][2] = 0.0;
195 } else {
196 d = sqrt(d);
197 m4[0][0] = d;
198 m4[1][0] = -co->ad[0]*co->ad[1]/d;
199 m4[2][0] = -co->ad[0]*co->ad[2]/d;
200 m4[1][1] = co->ad[2]/d;
201 m4[2][1] = -co->ad[1]/d;
202 m4[0][2] = co->ad[0];
203 m4[1][2] = co->ad[1];
204 m4[2][2] = co->ad[2];
205 }
206 multmat4(co->tm, co->tm, m4);
207
208 /* scale z-axis */
209 if (co->p0 != co->p1 & co->r0 != co->r1) {
210 setident4(m4);
211 m4[2][2] = (CO_R1(co) - CO_R0(co)) / co->al;
212 multmat4(co->tm, co->tm, m4);
213 }
214 }