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