ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/ot/sphere.c
Revision: 2.5
Committed: Tue Mar 30 16:13:00 2004 UTC (20 years ago) by schorsch
Content type: text/plain
Branch: MAIN
CVS Tags: rad4R2P2, rad5R0, rad3R7P2, rad3R7P1, rad4R2, rad4R1, rad4R0, rad3R6, rad3R6P1, rad3R8, rad3R9, rad4R2P1
Changes since 2.4: +1 -2 lines
Log Message:
Continued ANSIfication. There are only bits and pieces left now.

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: sphere.c,v 2.4 2004/03/27 12:41:45 schorsch Exp $";
3 #endif
4 /*
5 * sphere.c - routines for creating octrees for spheres.
6 *
7 * 7/28/85
8 */
9
10 #include "standard.h"
11
12 #include "octree.h"
13
14 #include "object.h"
15
16 #include "otypes.h"
17
18 #define ROOT3 1.732050808
19
20 /*
21 * Regrettably, the algorithm for determining a cube's location
22 * with respect to a sphere is not simple. First, a quick test is
23 * made to determine if the sphere and the bounding sphere of the cube
24 * are disjoint. This of course means no intersection. Failing this,
25 * we determine if the cube lies inside the sphere. The cube is
26 * entirely inside if the bounding sphere on the cube is
27 * contained within our sphere. This means no intersection. Otherwise,
28 * if the cube radius is smaller than the sphere's and the cube center is
29 * inside the sphere, we assume intersection. If these tests fail,
30 * we proceed as follows.
31 * The sphere center is located in relation to the 6 cube faces,
32 * and one of four things is done depending on the number of
33 * planes the center lies between:
34 *
35 * 0: The sphere is closest to a cube corner, find the
36 * distance to that corner.
37 *
38 * 1: The sphere is closest to a cube edge, find this
39 * distance.
40 *
41 * 2: The sphere is closest to a cube face, find the distance.
42 *
43 * 3: The sphere has its center inside the cube.
44 *
45 * In cases 0-2, if the closest part of the cube is within
46 * the radius distance from the sphere center, we have intersection.
47 * If it is not, the cube must be outside the sphere.
48 * In case 3, there must be intersection, and no further
49 * tests are necessary.
50 */
51
52
53 int
54 o_sphere( /* determine if sphere intersects cube */
55 OBJREC *o,
56 register CUBE *cu
57 )
58 {
59 FVECT v1;
60 double d1, d2;
61 register RREAL *fa;
62 register int i;
63 #define cent fa
64 #define rad fa[3]
65 /* get arguments */
66 if (o->oargs.nfargs != 4)
67 objerror(o, USER, "bad # arguments");
68 fa = o->oargs.farg;
69 if (rad < -FTINY) {
70 objerror(o, WARNING, "negative radius");
71 o->otype = o->otype == OBJ_SPHERE ?
72 OBJ_BUBBLE : OBJ_SPHERE;
73 rad = -rad;
74 } else if (rad <= FTINY)
75 objerror(o, USER, "zero radius");
76
77 d1 = ROOT3/2.0 * cu->cusize; /* bounding radius for cube */
78
79 d2 = cu->cusize * 0.5; /* get distance between centers */
80 for (i = 0; i < 3; i++)
81 v1[i] = cu->cuorg[i] + d2 - cent[i];
82 d2 = DOT(v1,v1);
83
84 if (d2 > (rad+d1+FTINY)*(rad+d1+FTINY)) /* quick test */
85 return(O_MISS); /* cube outside */
86
87 /* check sphere interior */
88 if (d1 < rad) {
89 if (d2 < (rad-d1-FTINY)*(rad-d1-FTINY))
90 return(O_MISS); /* cube inside sphere */
91 if (d2 < (rad+FTINY)*(rad+FTINY))
92 return(O_HIT); /* cube center inside */
93 }
94 /* find closest distance */
95 for (i = 0; i < 3; i++)
96 if (cent[i] < cu->cuorg[i])
97 v1[i] = cu->cuorg[i] - cent[i];
98 else if (cent[i] > cu->cuorg[i] + cu->cusize)
99 v1[i] = cent[i] - (cu->cuorg[i] + cu->cusize);
100 else
101 v1[i] = 0;
102 /* final intersection check */
103 if (DOT(v1,v1) <= (rad+FTINY)*(rad+FTINY))
104 return(O_HIT);
105 else
106 return(O_MISS);
107 }