001: /*
002: * Copyright (c) 2001 Silvere Martin-Michiellot All Rights Reserved.
003: *
004: * Silvere Martin-Michiellot grants you ("Licensee") a non-exclusive,
005: * royalty free, license to use, modify and redistribute this
006: * software in source and binary code form,
007: * provided that i) this copyright notice and license appear on all copies of
008: * the software; and ii) Licensee does not utilize the software in a manner
009: * which is disparaging to Silvere Martin-Michiellot.
010: *
011: * This software is provided "AS IS," without a warranty of any kind. ALL
012: * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
013: * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
014: * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. Silvere Martin-Michiellot
015: * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES
016: * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
017: * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
018: * Silvere Martin-Michiellot OR ITS LICENSORS BE LIABLE
019: * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
020: * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
021: * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
022: * OR INABILITY TO USE SOFTWARE, EVEN IF Silvere Martin-Michiellot HAS BEEN
023: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
024: *
025: * This software is not designed or intended for use in on-line control of
026: * aircraft, air traffic, aircraft navigation or aircraft communications; or in
027: * the design, construction, operation or maintenance of any nuclear
028: * facility. Licensee represents and warrants that it will not use or
029: * redistribute the Software for such purposes.
030: *
031: * @Author: Silvere Martin-Michiellot
032: *
033: */
034:
035: package com.db.server;
036:
037: /**
038: * A class that extends the BoundingSphere class to provide additional methods. We are only able to compute bounds for BoundingBox, BoundingSphere, BoundingPolytope or their sub-classes.
039: */
040:
041: import javax.media.j3d.*;
042: import javax.vecmath.*;
043:
044: public class ExtendedBoundingSphere extends BoundingSphere implements
045: ExtendedBounds {
046:
047: public ExtendedBoundingSphere() {
048:
049: super ();
050:
051: }
052:
053: public ExtendedBoundingSphere(Bounds boundsObject) {
054:
055: super (boundsObject);
056:
057: }
058:
059: public ExtendedBoundingSphere(Bounds[] boundsObjects) {
060:
061: super (boundsObjects);
062:
063: }
064:
065: public ExtendedBoundingSphere(Point3d center, double radius) {
066:
067: super (center, radius);
068:
069: }
070:
071: public double getVolume() {
072:
073: return 4 / 3 * Math.PI * this .getRadius();
074:
075: }
076:
077: public boolean contains(Point3d point3d) {
078:
079: BoundingSphere boundingSpherePoint3d;
080: double delta;
081:
082: delta = 0.000000001;
083:
084: boundingSpherePoint3d = new BoundingSphere(point3d, delta);
085:
086: return contains(boundingSpherePoint3d);
087:
088: }
089:
090: public boolean contains(Bounds bounds) {
091:
092: Bounds[] boundsArray;
093:
094: boundsArray = new Bounds[1];
095: boundsArray[0] = bounds;
096:
097: return this .contains(boundsArray);
098:
099: }
100:
101: public boolean contains(Bounds[] bounds) {
102:
103: ExtendedBoundingBox extendedBoundingBox1;
104: ExtendedBoundingBox extendedBoundingBox2;
105:
106: extendedBoundingBox1 = new ExtendedBoundingBox(this );
107: extendedBoundingBox2 = new ExtendedBoundingBox(bounds);
108:
109: //this should lead to a correct result and avoid complex conversions
110: return extendedBoundingBox2.contains(extendedBoundingBox2);
111:
112: }
113:
114: //this object is affected by the operation
115: //the result is stored in this and is thus a single BoundingSphere
116: //mostly useless because the resulting BoundingSphere will provide a very raw subtraction
117: public Bounds subtract(Bounds bounds) {
118:
119: Bounds[] boundsArray;
120:
121: boundsArray = new Bounds[1];
122: boundsArray[0] = bounds;
123:
124: return this .subtract(boundsArray);
125:
126: }
127:
128: //this object is affected by the operation
129: //the result is stored in this and is thus a single BoundingSphere
130: //mostly useless because the resulting BoundingSphere will provide a very raw subtraction
131: public Bounds subtract(Bounds[] bounds) {
132:
133: Point3d center1;
134: double radius1;
135: Point3d lower1;
136: Point3d upper1;
137: Point3d center2;
138: double radius2;
139: Point3d lower2;
140: Point3d upper2;
141: double minx, miny, minz, maxx, maxy, maxz;
142: BoundingSphere boundingSphere;
143:
144: center1 = new Point3d();
145: center2 = new Point3d();
146:
147: this .getCenter(center1);
148: radius1 = this .getRadius();
149:
150: lower1 = new Point3d(center1.x - radius1, center1.y - radius1,
151: center1.z - radius1);
152: upper1 = new Point3d(center1.x + radius1, center1.y + radius1,
153: center1.z + radius1);
154:
155: boundingSphere = new BoundingSphere(bounds);
156:
157: boundingSphere.getCenter(center2);
158: radius2 = boundingSphere.getRadius();
159:
160: //this is probably the way BoundingBoxes are computed from BoundingSpheres
161: lower2 = new Point3d(center2.x - radius2, center2.y - radius2,
162: center2.z - radius2);
163: upper2 = new Point3d(center2.x + radius2, center2.y + radius2,
164: center2.z + radius2);
165:
166: if (lower2.x > lower1.x) {
167: if (upper2.x < upper1.x) {
168: if ((lower2.x - lower1.x) > (upper1.x - upper2.x)) {
169: minx = lower1.x;
170: maxx = lower2.x;
171: } else {
172: minx = upper2.x;
173: maxx = upper1.x;
174: }
175: } else {
176: minx = lower1.x;
177: maxx = lower2.x;
178: }
179: } else {
180: if (upper2.x < upper1.x) {
181: minx = upper2.x;
182: maxx = upper1.x;
183: } else {
184: minx = 0;
185: maxx = 0;
186: }
187: }
188:
189: if (lower2.y > lower1.y) {
190: if (upper2.y < upper1.y) {
191: if ((lower2.y - lower1.y) > (upper1.y - upper2.y)) {
192: miny = lower1.x;
193: maxy = lower2.y;
194: } else {
195: miny = upper2.y;
196: maxy = upper1.y;
197: }
198: } else {
199: miny = lower1.y;
200: maxy = lower2.y;
201: }
202: } else {
203: if (upper2.y < upper1.y) {
204: miny = upper2.y;
205: maxy = upper1.y;
206: } else {
207: miny = 0;
208: maxy = 0;
209: }
210: }
211:
212: if (lower2.z > lower1.z) {
213: if (upper2.z < upper1.z) {
214: if ((lower2.z - lower1.z) > (upper1.z - upper2.z)) {
215: minz = lower1.z;
216: maxz = lower2.z;
217: } else {
218: minz = upper2.z;
219: maxz = upper1.z;
220: }
221: } else {
222: minz = lower1.z;
223: maxz = lower2.z;
224: }
225: } else {
226: if (upper2.z < upper1.z) {
227: minz = upper2.z;
228: maxz = upper1.z;
229: } else {
230: minz = 0;
231: maxz = 0;
232: }
233: }
234:
235: boundingSphere.setCenter(new Point3d(maxx - minx, maxy - miny,
236: maxz - minz));
237: boundingSphere.setRadius(Math.min(Math.min(maxz - minz, maxy
238: - miny), maxx - minx) / 2);
239:
240: return boundingSphere;
241:
242: }
243:
244: }
|