📄 boundingbox.java
字号:
if( this.intersect( sphere) ) { BoundingBox sbox = new BoundingBox( sphere ); this.intersect( sbox, newBoundBox ); return true; } else { // Negative volume. newBoundBox.setLower( 1.0d, 1.0d, 1.0d); newBoundBox.setUpper(-1.0d, -1.0d, -1.0d); return false; } // System.err.println("intersect Sphere "); } else if(boundsObject.boundId == BOUNDING_POLYTOPE) { BoundingPolytope polytope = (BoundingPolytope)boundsObject; if( this.intersect( polytope)) { BoundingBox pbox = new BoundingBox( polytope); // convert polytope to box this.intersect( pbox, newBoundBox ); return true; } else { // Negative volume. newBoundBox.setLower( 1.0d, 1.0d, 1.0d); newBoundBox.setUpper(-1.0d, -1.0d, -1.0d); return false; } } else { throw new IllegalArgumentException(J3dI18N.getString("BoundingBox7")); } } /** * Test for intersection with an array of bounds objects. * @param boundsObjects an array of bounds objects * @param newBoundBox the new bounding box which is the intersection of * the boundsObject and this BoundingBox * @return true or false indicating if an intersection occured */ public boolean intersect(Bounds[] boundsObjects, BoundingBox newBoundBox) { if( boundsObjects == null || boundsObjects.length <= 0 || boundsIsEmpty ) { // Negative volume. newBoundBox.setLower( 1.0d, 1.0d, 1.0d); newBoundBox.setUpper(-1.0d, -1.0d, -1.0d); 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. newBoundBox.setLower( 1.0d, 1.0d, 1.0d); newBoundBox.setUpper(-1.0d, -1.0d, -1.0d); return false; } boolean status = false; BoundingBox tbox = new BoundingBox(); for(;i<boundsObjects.length;i++) { if( boundsObjects[i] == null || boundsObjects[i].boundsIsEmpty) ; else if( boundsObjects[i].boundId == BOUNDING_BOX){ BoundingBox box = (BoundingBox)boundsObjects[i]; // both boxes are axis aligned if( upper.x > box.lower.x && box.upper.x > lower.x && upper.y > box.lower.y && box.upper.y > lower.y && upper.z > box.lower.z && box.upper.z > lower.z ){ if(upper.x > box.upper.x) newBoundBox.upper.x = box.upper.x; else newBoundBox.upper.x = upper.x; if(upper.y > box.upper.y) newBoundBox.upper.y = box.upper.y; else newBoundBox.upper.y = upper.y; if(upper.z > box.upper.z) newBoundBox.upper.z = box.upper.z; else newBoundBox.upper.z = upper.z; if(lower.x < box.lower.x) newBoundBox.lower.x = box.lower.x; else newBoundBox.lower.x = lower.x; if(lower.y < box.lower.y) newBoundBox.lower.y = box.lower.y; else newBoundBox.lower.y = lower.y; if(lower.z < box.lower.z) newBoundBox.lower.z = box.lower.z; else newBoundBox.lower.z = lower.z; status = true; newBoundBox.updateBoundsStates(); } } else if( boundsObjects[i].boundId == BOUNDING_SPHERE) { BoundingSphere sphere = (BoundingSphere)boundsObjects[i]; if( this.intersect(sphere)) { BoundingBox sbox = new BoundingBox( sphere ); // convert sphere to box this.intersect(sbox,tbox); // insersect two boxes if( status ) { newBoundBox.combine( tbox ); } else { newBoundBox.set( tbox ); status = true; } } } else if(boundsObjects[i].boundId == BOUNDING_POLYTOPE) { BoundingPolytope polytope = (BoundingPolytope)boundsObjects[i]; if( this.intersect( polytope)) { BoundingBox pbox = new BoundingBox( polytope ); // convert polytope to box this.intersect(pbox,tbox); // insersect two boxes if ( status ) { newBoundBox.combine( tbox ); } else { newBoundBox.set( tbox ); status = true; } } } else { throw new IllegalArgumentException(J3dI18N.getString("BoundingBox6")); } if(newBoundBox.boundsIsInfinite) break; // We're done. } if( status == false ) { // Negative volume. newBoundBox.setLower( 1.0d, 1.0d, 1.0d); newBoundBox.setUpper(-1.0d, -1.0d, -1.0d); } return status; } /** * Finds closest bounding object that intersects this bounding box. * @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; } getCenter(); 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( (centroid.x-cenX)*(centroid.x-cenX) + (centroid.y-cenY)*(centroid.y-cenY) + (centroid.z-cenZ)*(centroid.z-cenZ) ); inside = false; if( lower.x <= box.lower.x && lower.y <= box.lower.y && lower.z <= box.lower.z && upper.x >= box.upper.x && upper.y >= box.upper.y && upper.z >= box.upper.z ) { // box is contained inside = true; } 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 if( boundsObjects[i].boundId == BOUNDING_SPHERE ) { BoundingSphere sphere = (BoundingSphere)boundsObjects[i]; dis = Math.sqrt( (centroid.x-sphere.center.x)* (centroid.x-sphere.center.x) + (centroid.y-sphere.center.y)* (centroid.y-sphere.center.y) + (centroid.z-sphere.center.z)* (centroid.z-sphere.center.z) ); inside = false; // sphere sphere.center is inside box if(sphere.center.x <= upper.x && sphere.center.x >= lower.x && sphere.center.y <= upper.y && sphere.center.y >= lower.y && sphere.center.z <= upper.z && sphere.center.z >= lower.z ) { // check if sphere intersects any side if (sphere.center.x - lower.x >= sphere.radius && upper.x - sphere.center.x >= sphere.radius && sphere.center.y - lower.y >= sphere.radius && upper.y - sphere.center.y >= sphere.radius && sphere.center.z - lower.z >= sphere.radius && upper.z - sphere.center.z >= sphere.radius ) { // contains the sphere inside = true; } } if (inside ) { // initialize smallest_distance for the first containment if( !contains ){ 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( (centroid.x-polytope.centroid.x)* (centroid.x-polytope.centroid.x) + (centroid.y-polytope.centroid.y)* (centroid.y-polytope.centroid.y) + (centroid.z-polytope.centroid.z)* (centroid.z-polytope.centroid.z) ); inside = true; for(j=0;j<polytope.nVerts;j++) { if( polytope.verts[j].x < lower.x || polytope.verts[j].y < lower.y || polytope.verts[j].z < lower.z || polytope.verts[j].x > upper.x || polytope.verts[j].y > upper.y || polytope.verts[j].z > upper.z ) { // box contains polytope 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("BoundingBox9")); } } } if ( intersect ) return boundsObjects[index]; else return null; } /** * Tests for intersection of box and frustum. * @param frustum * @return true if they intersect */ boolean intersect(CachedFrustum frustum ) { if (boundsIsEmpty) return false; if(boundsIsInfinite) return true; // System.err.println("intersect frustum with box="+this.toString()); // System.err.println("frustum "+frustum.toString()); // check if box and bounding box of frustum intersect if ((upper.x < frustum.lower.x) || (lower.x > frustum.upper.x) || (upper.y < frustum.lower.y) || (lower.y > frustum.upper.y) || (upper.z < frustum.lower.z) || (lower.z > frustum.upper.z) ) { // System.err.println("*** box and bounding box of frustum do not intersect"); return false; } // check if all box points out any frustum plane int i = 5; while (i>=0){ Vector4d vc = frustum.clipPlanes[i--]; if ((( upper.x*vc.x + upper.y*vc.y + upper.z*vc.z + vc.w ) < 0.0 ) && (( upper.x*vc.x + lower.y*vc.y + upper.z*vc.z + vc.w ) < 0.0 ) && (( upper.x*vc.x + lower.y*vc.y + lower.z*vc.z + vc.w ) < 0.0 ) && (( upper.x*vc.x + upper.y*vc.y + lower.z*vc.z + vc.w ) < 0.0 ) && (( lower.x*vc.x + upper.y*vc.y + upper.z*vc.z + vc.w ) < 0.0 ) && (( lower.x*vc.x + lower.y*vc.y + upper.z*vc.z + vc.w ) < 0.0 ) && (( lower.x*vc.x + lower.y*vc.y + lower.z*vc.z + vc.w ) < 0.0 ) && (( lower.x*vc.x + upper.y*vc.y + lower.z*vc.z + vc.w ) < 0.0 )) { // all corners outside this frustum plane // System.err.println("*** all corners outside this frustum plane"); return false; } } return true; } /** * Returns a string representation of this class. */ public String toString() { return new String( "Bounding box: Lower="+lower.x+" "+ lower.y+" "+lower.z+" Upper="+upper.x+" "+ upper.y+" "+upper.z ); } private void updateBoundsStates() { if((lower.x == Double.NEGATIVE_INFINITY) && (lower.y == Double.NEGATIVE_INFINITY) && (lower.z == Double.NEGATIVE_INFINITY) && (upper.x == Double.POSITIVE_INFINITY) && (upper.y == Double.POSITIVE_INFINITY) && (upper.z == Double.POSITIVE_INFINITY)) { boundsIsEmpty = false; boundsIsInfinite = true; return; } if (checkBoundsIsNaN()) { boundsIsEmpty = true; boundsIsInfinite = false; return; } else { boundsIsInfinite = false; if( lower.x > upper.x || lower.y > upper.y || lower.z > upper.z ) { boundsIsEmpty = true; } else { boundsIsEmpty = false; } } } // For a infinite bounds. What is the centroid ? Point3d getCenter() { if(centroid == null) { centroid = new Point3d(); } centroid.x = (upper.x+lower.x)*0.5; centroid.y = (upper.y+lower.y)*0.5; centroid.z = (upper.z+lower.z)*0.5; return centroid; } void translate(BoundingBox bbox, Vector3d value) { if (bbox == null || bbox.boundsIsEmpty) { // Negative volume. setLower( 1.0d, 1.0d, 1.0d); setUpper(-1.0d, -1.0d, -1.0d); return; } if(bbox.boundsIsInfinite) { this.set(bbox); return; } lower.x = bbox.lower.x + value.x; lower.y = bbox.lower.y + value.y; lower.z = bbox.lower.z + value.z; upper.x = bbox.upper.x + value.x; upper.y = bbox.upper.y + value.y; upper.z = bbox.upper.z + value.z; } /** * 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) { BoundingBox region = (BoundingBox) r; region.lower.x = lower.x; region.lower.y = lower.y; region.lower.z = lower.z; region.upper.x = upper.x; region.upper.y = upper.y; region.upper.z = upper.z; region.boundsIsEmpty = boundsIsEmpty; region.boundsIsInfinite = boundsIsInfinite; return region; } else { return (Bounds) this.clone(); } } // Check is any of the bounds is a NaN, if yes, then // set it an empty bounds boolean checkBoundsIsNaN() { if (Double.isNaN(lower.x+lower.y+lower.z+upper.x+upper.y+upper.z)) { return true; } return false; } int getPickType() { return PickShape.PICKBOUNDINGBOX; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -