ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/cone.c
Revision: 1.1
Committed: Thu Feb 2 10:34:30 1989 UTC (35 years, 3 months ago) by greg
Content type: text/plain
Branch: MAIN
Log Message:
Initial revision

File Contents

# Content
1 /* Copyright (c) 1986 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 double fabs(), sqrt();
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 goto raderr;
67 co->r0 = co->r1 = 6;
68 } else {
69 if (o->oargs.nfargs != 8)
70 goto argcerr;
71 if (co->ca[6] < 0.0 || co->ca[7] < 0.0)
72 goto raderr;
73 if (fabs(co->ca[7] - co->ca[6]) <= FTINY)
74 goto raderr;
75 co->r0 = 6;
76 co->r1 = 7;
77 }
78 /* get axis orientation */
79 co->p0 = 0;
80 if (o->otype == OBJ_RING) {
81 if (co->ca[6] > co->ca[7]) { /* make r0 smaller */
82 co->r0 = 7;
83 co->r1 = 6;
84 }
85 co->p1 = 0;
86 VCOPY(co->ad, o->oargs.farg+3);
87 } else {
88 co->p1 = 3;
89 co->ad[0] = co->ca[3] - co->ca[0];
90 co->ad[1] = co->ca[4] - co->ca[1];
91 co->ad[2] = co->ca[5] - co->ca[2];
92 }
93 co->al = normalize(co->ad);
94 if (co->al == 0.0)
95 objerror(o, USER, "zero orientation");
96 /* compute axis and side lengths */
97 if (o->otype == OBJ_RING) {
98 co->al = 0.0;
99 co->sl = co->ca[co->r1] - co->ca[co->r0];
100 } else if (o->otype == OBJ_CONE || o->otype == OBJ_CUP) {
101 co->sl = co->ca[7] - co->ca[6];
102 co->sl = sqrt(co->sl*co->sl + co->al*co->al);
103 } else { /* OBJ_CYLINDER || OBJ_TUBE */
104 co->sl = co->al;
105 }
106 co->tm = NULL;
107 (CONE *)o->os = co;
108 }
109 if (getxf && co->tm == NULL)
110 conexform(co);
111 return(co);
112
113 argcerr:
114 objerror(o, USER, "bad # arguments");
115 raderr:
116 objerror(o, USER, "illegal radii");
117 }
118
119
120 freecone(o) /* free memory associated with cone */
121 OBJREC *o;
122 {
123 register CONE *co = (CONE *)o->os;
124
125 if (co->tm != NULL)
126 free((char *)co->tm);
127 free(o->os);
128 o->os = NULL;
129 }
130
131
132 conexform(co) /* get cone transformation matrix */
133 register CONE *co;
134 {
135 double sqrt(), fabs();
136 double m4[4][4];
137 register double d;
138 register int i;
139
140 co->tm = (double (*)[4])malloc(sizeof(m4));
141 if (co->tm == NULL)
142 error(SYSTEM, "out of memory in conexform");
143
144 /* translate to origin */
145 setident4(co->tm);
146 if (co->r0 == co->r1)
147 d = 0.0;
148 else
149 d = co->ca[co->r0] / (co->ca[co->r1] - co->ca[co->r0]);
150 for (i = 0; i < 3; i++)
151 co->tm[3][i] = d*(co->ca[co->p1+i] - co->ca[co->p0+i])
152 - co->ca[co->p0+i];
153
154 /* rotate to positive z-axis */
155 setident4(m4);
156 d = co->ad[1]*co->ad[1] + co->ad[2]*co->ad[2];
157 if (d <= FTINY*FTINY) {
158 m4[0][0] = 0.0;
159 m4[0][2] = co->ad[0];
160 m4[2][0] = -co->ad[0];
161 m4[2][2] = 0.0;
162 } else {
163 d = sqrt(d);
164 m4[0][0] = d;
165 m4[1][0] = -co->ad[0]*co->ad[1]/d;
166 m4[2][0] = -co->ad[0]*co->ad[2]/d;
167 m4[1][1] = co->ad[2]/d;
168 m4[2][1] = -co->ad[1]/d;
169 m4[0][2] = co->ad[0];
170 m4[1][2] = co->ad[1];
171 m4[2][2] = co->ad[2];
172 }
173 multmat4(co->tm, co->tm, m4);
174
175 /* scale z-axis */
176 setident4(m4);
177 if (co->p0 != co->p1 && co->r0 != co->r1) {
178 d = fabs(co->ca[co->r1] - co->ca[co->r0]);
179 m4[2][2] = d/co->al;
180 }
181 multmat4(co->tm, co->tm, m4);
182 }