📄 boundingsphere.java
字号:
} else if( dis+radius <= sphere.radius ) { // this sphere is contained within boundsObject newBoundSphere.center.x = center.x; newBoundSphere.center.y = center.y; newBoundSphere.center.z = center.z; newBoundSphere.radius = radius; status = true; } else if( dis+sphere.radius <= radius ) { // boundsObject is containted within this sphere newBoundSphere.center.x = sphere.center.x; newBoundSphere.center.y = sphere.center.y; newBoundSphere.center.z = sphere.center.z; newBoundSphere.radius = sphere.radius; status = true; } else { // distance from this center to center of overlapped volume d2 = (dis*dis + radius*radius - sphere.radius*sphere.radius)/(2.0*dis); newBoundSphere.radius = Math.sqrt( radius*radius - d2*d2); t = d2/dis; newBoundSphere.center.x = center.x + (sphere.center.x - center.x)*t; newBoundSphere.center.y = center.y + (sphere.center.y - center.y)*t; newBoundSphere.center.z = center.z + (sphere.center.z - center.z)*t; status = true; } newBoundSphere.updateBoundsStates(); return status; } else if(boundsObject.boundId == BOUNDING_POLYTOPE) { BoundingBox tbox = new BoundingBox(); BoundingPolytope polytope = (BoundingPolytope)boundsObject; if( this.intersect( polytope) ){ BoundingBox sbox = new BoundingBox( this ); // convert sphere to box BoundingBox pbox = new BoundingBox( polytope ); // convert polytope to box sbox.intersect(pbox,tbox); // insersect two boxes newBoundSphere.set( tbox ); // set sphere to the intersection of 2 boxesf return true; } else { // Negative volume. newBoundSphere.center.x = newBoundSphere.center.y = newBoundSphere.center.z = 0.0; newBoundSphere.radius = -1.0; newBoundSphere.updateBoundsStates(); return false; } } else { throw new IllegalArgumentException(J3dI18N.getString("BoundingSphere8")); } } /** * Test for intersection with an array of bounds objects. * @param boundsObjects an array of bounds objects * @param newBoundSphere the new bounding sphere which is the intersection of * the boundsObject and this BoundingSphere * @return true or false indicating if an intersection occured */ public boolean intersect(Bounds[] boundsObjects, BoundingSphere newBoundSphere) { if( boundsObjects == null || boundsObjects.length <= 0 || boundsIsEmpty ) { // Negative volume. newBoundSphere.center.x = newBoundSphere.center.y = newBoundSphere.center.z = 0.0; newBoundSphere.radius = -1.0; newBoundSphere.updateBoundsStates(); return false; } int i=0; // find first non null bounds object while( boundsObjects[i] == null && i < boundsObjects.length) { i++; } if( i >= boundsObjects.length ) { // all bounds objects were empty // Negative volume. newBoundSphere.center.x = newBoundSphere.center.y = newBoundSphere.center.z = 0.0; newBoundSphere.radius = -1.0; newBoundSphere.updateBoundsStates(); return false; } boolean status = false; double newRadius; Point3d newCenter = new Point3d(); BoundingBox tbox = new BoundingBox(); for(i=0;i<boundsObjects.length;i++) { if( boundsObjects[i] == null || boundsObjects[i].boundsIsEmpty) ; else if( boundsObjects[i].boundId == BOUNDING_BOX) { BoundingBox box = (BoundingBox)boundsObjects[i]; if( this.intersect( box) ){ BoundingBox sbox = new BoundingBox( this ); // convert sphere to box sbox.intersect(box,tbox); // insersect two boxes if( status ) { newBoundSphere.combine( tbox ); } else { newBoundSphere.set( tbox ); // set sphere to the intersection of 2 boxesf status = true; } } } else if( boundsObjects[i].boundId == BOUNDING_SPHERE ) { BoundingSphere sphere = (BoundingSphere)boundsObjects[i]; double dis,t,d2; dis = Math.sqrt( (center.x-sphere.center.x)*(center.x-sphere.center.x) + (center.y-sphere.center.y)*(center.y-sphere.center.y) + (center.z-sphere.center.z)*(center.z-sphere.center.z) ); if ( dis > radius+sphere.radius) { } else if( dis+radius <= sphere.radius ) { // this sphere is contained within boundsObject if( status ) { newBoundSphere.combine( this ); } else { newBoundSphere.center.x = center.x; newBoundSphere.center.y = center.y; newBoundSphere.center.z = center.z; newBoundSphere.radius = radius; status = true; newBoundSphere.updateBoundsStates(); } } else if( dis+sphere.radius <= radius ) { // boundsObject is containted within this sphere if( status ) { newBoundSphere.combine( sphere ); } else { newBoundSphere.center.x = center.x; newBoundSphere.center.y = center.y; newBoundSphere.center.z = center.z; newBoundSphere.radius = sphere.radius; status = true; newBoundSphere.updateBoundsStates(); } } else { // distance from this center to center of overlapped volume d2 = (dis*dis + radius*radius - sphere.radius*sphere.radius)/(2.0*dis); newRadius = Math.sqrt( radius*radius - d2*d2); t = d2/dis; newCenter.x = center.x + (sphere.center.x - center.x)*t; newCenter.y = center.y + (sphere.center.y - center.y)*t; newCenter.z = center.z + (sphere.center.z - center.z)*t; if( status ) { BoundingSphere newSphere = new BoundingSphere( newCenter, newRadius ); newBoundSphere.combine( newSphere ); } else { newBoundSphere.setRadius( newRadius ); newBoundSphere.setCenter( newCenter ); status = true; } } } else if(boundsObjects[i].boundId == BOUNDING_POLYTOPE) { BoundingPolytope polytope = (BoundingPolytope)boundsObjects[i]; if( this.intersect( polytope) ){ BoundingBox sbox = new BoundingBox( this ); // convert sphere to box BoundingBox pbox = new BoundingBox( polytope ); // convert polytope to box sbox.intersect(pbox, tbox); // insersect two boxes if( status ) { newBoundSphere.combine( tbox ); } else { newBoundSphere.set( tbox ); // set sphere to the intersection of 2 boxesf status = true; } } } else { throw new IllegalArgumentException(J3dI18N.getString("BoundingSphere9")); } } if( status == false) { // Negative volume. newBoundSphere.center.x = newBoundSphere.center.y = newBoundSphere.center.z = 0.0; newBoundSphere.radius = -1.0; newBoundSphere.updateBoundsStates(); } return status; } /** * Finds closest bounding object that intersects this bounding sphere. * @param boundsObjects an array of bounds objects * @return closest bounding object */ public Bounds closestIntersection( Bounds[] boundsObjects) { if( boundsObjects == null || boundsObjects.length <= 0 ) { return null; } if( boundsIsEmpty ) { return null; } double dis,far_dis,pdist,x,y,z,rad_sq; double cenX = 0.0, cenY = 0.0, cenZ = 0.0; boolean contains = false; boolean inside; boolean intersect = false; double smallest_distance = Double.MAX_VALUE; int i,j,index=0; for(i = 0; i < boundsObjects.length; i++){ if( boundsObjects[i] == null ) ; else if( this.intersect( boundsObjects[i])) { intersect = true; if(boundsObjects[i].boundId == BOUNDING_BOX){ BoundingBox box = (BoundingBox)boundsObjects[i]; cenX = (box.upper.x+box.lower.x)/2.0; cenY = (box.upper.y+box.lower.y)/2.0; cenZ = (box.upper.z+box.lower.z)/2.0; dis = Math.sqrt( (center.x-cenX)*(center.x-cenX) + (center.y-cenY)*(center.y-cenY) + (center.z-cenZ)*(center.z-cenZ) ); if( (center.x-box.lower.x)*(center.x-box.lower.x) > (center.x-box.upper.x)*(center.x-box.upper.x) ) far_dis = (center.x-box.lower.x)*(center.x-box.lower.x); else far_dis = (center.x-box.upper.x)*(center.x-box.upper.x); if( (center.y-box.lower.y)*(center.y-box.lower.y) > (center.y-box.upper.y)*(center.y-box.upper.y) ) far_dis += (center.y-box.lower.y)*(center.y-box.lower.y); else far_dis += (center.y-box.upper.y)*(center.y-box.upper.y); if( (center.z-box.lower.z)*(center.z-box.lower.z) > (center.z-box.upper.z)*(center.z-box.upper.z) ) far_dis += (center.z-box.lower.z)*(center.z-box.lower.z); else far_dis += (center.z-box.upper.z)*(center.z-box.upper.z); rad_sq = radius * radius; if( far_dis <= rad_sq ) { // contains box if( !contains ){ // initialize smallest_distance for the first containment index = i; smallest_distance = dis; contains = true; } else{ if( dis < smallest_distance){ index = i; smallest_distance = dis; } } } else if (!contains) { if( dis < smallest_distance){ index = i; smallest_distance = dis; } } } else if( boundsObjects[i].boundId == BOUNDING_SPHERE ) { BoundingSphere sphere = (BoundingSphere)boundsObjects[i]; dis = Math.sqrt( (center.x-sphere.center.x)*(center.x-sphere.center.x) + (center.y-sphere.center.y)*(center.y-sphere.center.y) + (center.z-sphere.center.z)*(center.z-sphere.center.z) ); if( (dis+sphere.radius) <= radius) { // contains the sphere if( !contains ){ // initialize smallest_distance for the first containment index = i; smallest_distance = dis; contains = true; } else{ if( dis < smallest_distance){ index = i; smallest_distance = dis; } } } else if (!contains) { if( dis < smallest_distance){ index = i; smallest_distance = dis; } } } else if(boundsObjects[i].boundId == BOUNDING_POLYTOPE) { BoundingPolytope polytope = (BoundingPolytope)boundsObjects[i]; dis = Math.sqrt( (center.x-polytope.centroid.x)*(center.x-polytope.centroid.x) + (center.y-polytope.centroid.y)*(center.y-polytope.centroid.y) + (center.z-polytope.centroid.z)*(center.z-polytope.centroid.z) ); inside = true; for(j=0;j<polytope.nVerts;j++) { x = polytope.verts[j].x - center.x; y = polytope.verts[j].y - center.y; z = polytope.verts[j].z - center.z; pdist = x*x + y*y + z*z; if( pdist > radius*radius) inside=false; } if( inside ) { if( !contains ){ // initialize smallest_distance for the first containment index = i; smallest_distance = dis; contains = true; } else{ if( dis < smallest_distance){ index = i; smallest_distance = dis; } } } else if (!contains) { if( dis < smallest_distance){ index = i; smallest_distance = dis; } } } else { throw new IllegalArgumentException(J3dI18N.getString("BoundingSphere10")); } } } if ( intersect ) return boundsObjects[index]; else return null; } /** * Intersects this bounding sphere with preprocessed frustum. * @return true if the bounding sphere and frustum intersect. */ boolean intersect(CachedFrustum frustum) { int i; double dist; if( boundsIsEmpty ) { return false; } if(boundsIsInfinite) return true; for (i=0; i<6; i++) { dist = frustum.clipPlanes[i].x*center.x + frustum.clipPlanes[i].y*center.y + frustum.clipPlanes[i].z*center.z + frustum.clipPlanes[i].w; if (dist < 0.0 && (dist + radius) < 0.0) { return(false); } } return true; } /** * This intersects this bounding sphere with 6 frustum plane equations * @return returns true if the bounding sphere and frustum intersect. */ boolean intersect(Vector4d[] planes) { int i; double dist; if( boundsIsEmpty ) { return false; } if(boundsIsInfinite) return true; for (i=0; i<6; i++) { dist = planes[i].x*center.x + planes[i].y*center.y + planes[i].z*center.z + planes[i].w; if (dist < 0.0 && (dist + radius) < 0.0) { //System.err.println("Tossing " + i + " " + dist + " " + radius); return(false); } } return true; } /** * Returns a string representation of this class. */ public String toString() { return new String( "Center="+center+" Radius="+radius); } private void updateBoundsStates() { if (checkBoundsIsNaN()) { boundsIsEmpty = true; boundsIsInfinite = false; return; } if(radius == Double.POSITIVE_INFINITY) { boundsIsEmpty = false; boundsIsInfinite = true; } else { boundsIsInfinite = false; if( radius < 0.0 ) { boundsIsEmpty = true; } else { boundsIsEmpty = false; } } } Point3d getCenter() { return center; } /** * if the passed the "region" is same type as this object * then do a copy, otherwise clone the Bounds and * return */ Bounds copy(Bounds r) { if (r != null && this.boundId == r.boundId) { BoundingSphere region = (BoundingSphere)r; region.radius = radius; region.center.x = center.x; region.center.y = center.y; region.center.z = center.z; region.boundsIsEmpty = boundsIsEmpty; region.boundsIsInfinite = boundsIsInfinite; return region; } else { return (Bounds) this.clone(); } } boolean checkBoundsIsNaN() { if (Double.isNaN(radius+center.x+center.y+center.z)) { return true; } return false; } int getPickType() { return PickShape.PICKBOUNDINGSPHERE; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -