📄 boundingbox.java
字号:
* @return true or false indicating if an intersection occured */ boolean intersect( Point3d start, Point3d end, Point4d position ) { double t1,t2,tmp,tnear,tfar,invDir,invMag; double dirx, diry, dirz; if( boundsIsEmpty ) { return false; } if( boundsIsInfinite ) { position.x = start.x; position.y = start.y; position.z = start.z; position.w = 0.0; return true; } dirx = end.x - start.x; diry = end.y - start.y; dirz = end.z - start.z; double dirLen = dirx*dirx + diry*diry + dirz*dirz; // Optimization : Handle zero length direction vector. if(dirLen == 0.0) return intersect(start, position); dirLen = Math.sqrt(dirLen); // System.err.println("dirLen is " + dirLen); invMag = 1.0/dirLen; dirx = dirx*invMag; diry = diry*invMag; dirz = dirz*invMag; /* System.err.println("dir = " + dir); System.err.println("start = " + start); System.err.println("lower = " + lower); System.err.println("upper = " + upper); */ // initialize tnear and tfar to handle dir.? == 0 cases tnear = -Double.MAX_VALUE; tfar = Double.MAX_VALUE; if(dirx == 0.0) { //System.err.println("dirx == 0.0"); if (start.x < lower.x || start.x > upper.x ) { //System.err.println( "parallel to x plane and outside"); return false; } } else { invDir = 1.0/dirx; t1 = (lower.x-start.x)*invDir; t2 = (upper.x-start.x)*invDir; //System.err.println("x t1 = " + t1 + " t2 = " + t2); if( t1 > t2) { tnear = t2; tfar = t1; }else { tnear = t1; tfar = t2; } if( tfar < 0.0 ) { //System.err.println( "x failed: tnear="+tnear+" tfar="+tfar); return false; } //System.err.println("x tnear = " + tnear + " tfar = " + tfar); } // y if (diry == 0.0) { //System.err.println("diry == 0.0"); if( start.y < lower.y || start.y > upper.y ){ //System.err.println( "parallel to y plane and outside"); return false; } } else { invDir = 1.0/diry; //System.err.println("invDir = " + invDir); t1 = (lower.y-start.y)*invDir; t2 = (upper.y-start.y)*invDir; if( t1 > t2) { tmp = t1; t1 = t2; t2 = tmp; } //System.err.println("y t1 = " + t1 + " t2 = " + t2); if( t1 > tnear) tnear = t1; if( t2 < tfar ) tfar = t2; if( (tfar < 0.0) || (tnear > tfar)){ //System.err.println( "y failed: tnear="+tnear+" tfar="+tfar); return false; } //System.err.println("y tnear = " + tnear + " tfar = " + tfar); } // z if (dirz == 0.0) { //System.err.println("dirz == 0.0"); if( start.z < lower.z || start.z > upper.z ) { //System.err.println( "parallel to z plane and outside"); return false; } } else { invDir = 1.0/dirz; t1 = (lower.z-start.z)*invDir; t2 = (upper.z-start.z)*invDir; if( t1 > t2) { tmp = t1; t1 = t2; t2 = tmp; } //System.err.println("z t1 = " + t1 + " t2 = " + t2); if( t1 > tnear) tnear = t1; if( t2 < tfar ) tfar = t2; if( (tfar < 0.0) || (tnear > tfar)){ //System.err.println( "z failed: tnear="+tnear+" tfar="+tfar); return false; } //System.err.println("z tnear = " + tnear + " tfar = " + tfar); } if((tnear < 0.0) && (tfar >= 0.0)) { // origin is inside the BBox. position.x = start.x + dirx*tfar; position.y = start.y + diry*tfar; position.z = start.z + dirz*tfar; position.w = tfar; } else { if(tnear>dirLen) { // Segment is behind BBox. /* System.err.println("PickSegment : intersected postion : " + position + " tnear " + tnear + " tfar " + tfar ); */ return false; } position.x = start.x + dirx*tnear; position.y = start.y + diry*tnear; position.z = start.z + dirz*tnear; position.w = tnear; } /* System.err.println("tnear = " + tnear + " tfar = " + tfar + " w " + position.w); System.err.println("lower = " + lower); System.err.println("upper = " + upper + "\n"); */ return true; } /** * Test for intersection with a ray. * @param origin the starting point of the ray * @param direction the direction of the ray * @return true or false indicating if an intersection occured */ public boolean intersect(Point3d origin, Vector3d direction ) { if( boundsIsEmpty ) { return false; } if( boundsIsInfinite ) { return true; } Point3d p=new Point3d(); return intersect( origin, direction, p ); } /** * A protected intersect method that returns the point of intersection. * Used by Picking methods to sort or return closest picked item. */ boolean intersect(Point3d origin, Vector3d direction, Point3d intersect ) { double theta=0.0; if( boundsIsEmpty ) { return false; } if( boundsIsInfinite ) { intersect.x = origin.x; intersect.y = origin.y; intersect.z = origin.z; return true; } if (direction.x > 0.0 ) theta = Math.max( theta, (lower.x - origin.x)/direction.x ); if (direction.x < 0.0 ) theta = Math.max( theta, (upper.x - origin.x)/direction.x ); if (direction.y > 0.0 ) theta = Math.max( theta, (lower.y - origin.y)/direction.y ); if (direction.y < 0.0 ) theta = Math.max( theta, (upper.y - origin.y)/direction.y ); if (direction.z > 0.0 ) theta = Math.max( theta, (lower.z - origin.z)/direction.z ); if (direction.z < 0.0 ) theta = Math.max( theta, (upper.z - origin.z)/direction.z ); intersect.x = origin.x + theta*direction.x; intersect.y = origin.y + theta*direction.y; intersect.z = origin.z + theta*direction.z; if (intersect.x < (lower.x-EPS)) return false; if (intersect.x > (upper.x+EPS)) return false; if (intersect.y < (lower.y-EPS)) return false; if (intersect.y > (upper.y+EPS)) return false; if (intersect.z < (lower.z-EPS)) return false; if (intersect.z > (upper.z+EPS)) return false; return true; } /** * Test for intersection with a point. * @param point a point defining a position in 3-space * @return true or false indicating if an intersection occured */ public boolean intersect(Point3d point ) { if( boundsIsEmpty ) { return false; } if( boundsIsInfinite ) { return true; } if( point.x <= upper.x && point.x >= lower.x && point.y <= upper.y && point.y >= lower.y && point.z <= upper.z && point.z >= lower.z) return true; else return false; } /** * Tests whether the bounding box is empty. A bounding box is * empty if it is null (either by construction or as the result of * a null intersection) or if its volume is negative. A bounding box * with a volume of zero is <i>not</i> empty. * @return true if the bounding box is empty; otherwise, it returns false */ public boolean isEmpty() { return boundsIsEmpty; } /** * Test for intersection with another bounds object. * @param boundsObject another bounds object * @return true or false indicating if an intersection occured */ boolean intersect(Bounds boundsObject, Point4d position) { return intersect(boundsObject); } /** * Test for intersection with another bounds object. * @param boundsObject another bounds object * @return true or false indicating if an intersection occured */ public boolean intersect(Bounds boundsObject) { if( boundsObject == null ) { return false; } if( boundsIsEmpty || boundsObject.boundsIsEmpty ) { return false; } if( boundsIsInfinite || boundsObject.boundsIsInfinite ) { return true; } if( boundsObject.boundId == BOUNDING_BOX){ BoundingBox box = (BoundingBox)boundsObject; // 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 ) return true; else return false; } else if( boundsObject.boundId == BOUNDING_SPHERE) { BoundingSphere sphere = (BoundingSphere)boundsObject; double rad_sq = sphere.radius*sphere.radius; double dis = 0.0; if( sphere.center.x < lower.x ) dis = (sphere.center.x-lower.x)*(sphere.center.x-lower.x); else if( sphere.center.x > upper.x ) dis = (sphere.center.x-upper.x)*(sphere.center.x-upper.x); if( sphere.center.y < lower.y ) dis += (sphere.center.y-lower.y)*(sphere.center.y-lower.y); else if( sphere.center.y > upper.y ) dis += (sphere.center.y-upper.y)*(sphere.center.y-upper.y); if( sphere.center.z < lower.z ) dis += (sphere.center.z-lower.z)*(sphere.center.z-lower.z); else if( sphere.center.z > upper.z ) dis += (sphere.center.z-upper.z)*(sphere.center.z-upper.z); if( dis <= rad_sq ) return true; else return false; } else if(boundsObject.boundId == BOUNDING_POLYTOPE) { // intersect an axis aligned box with a polytope return intersect_ptope_abox ( (BoundingPolytope)boundsObject, this ); } else { throw new IllegalArgumentException(J3dI18N.getString("BoundingBox6")); } } /** * Test for intersection with an array of bounds objects. * @param boundsObjects an array of bounding objects * @return true or false indicating if an intersection occured */ public boolean intersect(Bounds[] boundsObjects) { double distsq, radsq; int i; if( boundsObjects == null || boundsObjects.length <= 0 ) { return false; } if( boundsIsEmpty ) { return false; } for(i = 0; i < boundsObjects.length; i++){ if( boundsObjects[i] == null || boundsObjects[i].boundsIsEmpty) ; else if( boundsIsInfinite || boundsObjects[i].boundsIsInfinite ) { return true; // We're done here. } 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 ) return true; } else if( boundsObjects[i].boundId == BOUNDING_SPHERE ) { BoundingSphere sphere = (BoundingSphere)boundsObjects[i]; double rad_sq = sphere.radius*sphere.radius; double dis = 0.0; if( sphere.center.x < lower.x ) dis = (sphere.center.x-lower.x)*(sphere.center.x-lower.x); else if( sphere.center.x > upper.x ) dis = (sphere.center.x-upper.x)*(sphere.center.x-upper.x); if( sphere.center.y < lower.y ) dis += (sphere.center.y-lower.y)*(sphere.center.y-lower.y); else if( sphere.center.y > upper.y ) dis += (sphere.center.y-upper.y)*(sphere.center.y-upper.y); if( sphere.center.z < lower.z ) dis += (sphere.center.z-lower.z)*(sphere.center.z-lower.z); else if( sphere.center.z > upper.z ) dis += (sphere.center.z-upper.z)*(sphere.center.z-upper.z); if( dis <= rad_sq ) return true; } else if(boundsObjects[i].boundId == BOUNDING_POLYTOPE) { if( intersect_ptope_abox ( (BoundingPolytope)boundsObjects[i], this )) return true; } else { // System.err.println("intersect ?? "); } } return false; } /** * Test for intersection with another bounding box. * @param boundsObject another bounding object * @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 boundsObject, BoundingBox newBoundBox) { if((boundsObject == null) || boundsIsEmpty || boundsObject.boundsIsEmpty ) { // Negative volume. newBoundBox.setLower( 1.0d, 1.0d, 1.0d); newBoundBox.setUpper(-1.0d, -1.0d, -1.0d); return false; } if(boundsIsInfinite && (!boundsObject.boundsIsInfinite)) { newBoundBox.set(boundsObject); return true; } else if((!boundsIsInfinite) && boundsObject.boundsIsInfinite) { newBoundBox.set(this); return true; } else if(boundsIsInfinite && boundsObject.boundsIsInfinite) { newBoundBox.set(this); return true; } else if( boundsObject.boundId == BOUNDING_BOX){ BoundingBox box = (BoundingBox)boundsObject; // 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; newBoundBox.updateBoundsStates(); return true; } else { // Negative volume. newBoundBox.setLower( 1.0d, 1.0d, 1.0d); newBoundBox.setUpper(-1.0d, -1.0d, -1.0d); return false; } } else if( boundsObject.boundId == BOUNDING_SPHERE) { BoundingSphere sphere = (BoundingSphere)boundsObject;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -