📄 boundingsphere.java
字号:
/** * Test for intersection with a point * @param point the pick point * @param position a point defining the location of the pick w= distance to pick * @return true or false indicating if an intersection occured */ boolean intersect(Point3d point, Point4d position ) { double x,y,z,dist; if( boundsIsEmpty ) { return false; } if( boundsIsInfinite ) { position.x = point.x; position.y = point.y; position.z = point.z; position.w = 0.0; return true; } x = point.x - center.x; y = point.y - center.y; z = point.z - center.z; dist = x*x + y*y + z*z; if( dist > radius*radius) return false; else { position.x = point.x; position.y = point.y; position.z = point.z; position.w = Math.sqrt(dist); return true; } } /** * Test for intersection with a segment * @param start a point defining the start of the line segment * @param end a point defining the end of the line segment * @param position a point defining the location of the pick w= distance to pick * @return true or false indicating if an intersection occured */ boolean intersect( Point3d start, Point3d end, Point4d position ) { if( boundsIsEmpty ) { return false; } if( boundsIsInfinite ) { position.x = start.x; position.y = start.y; position.z = start.z; position.w = 0.0; return true; } double l2oc,rad2,tca,t2hc,mag,invMag,t; Vector3d dir = new Vector3d(); // normalized direction of ray Point3d oc = new Point3d(); // vector from sphere center to ray origin Vector3d direction = new Vector3d(); oc.x = center.x - start.x; oc.y = center.y - start.y; oc.z = center.z - start.z; direction.x = end.x - start.x; direction.y = end.y - start.y; direction.z = end.z - start.z; invMag = 1.0/Math.sqrt( direction.x*direction.x + direction.y*direction.y + direction.z*direction.z); dir.x = direction.x*invMag; dir.y = direction.y*invMag; dir.z = direction.z*invMag; l2oc = oc.x*oc.x + oc.y*oc.y + oc.z*oc.z; // center to origin squared rad2 = radius*radius; if( l2oc < rad2 ){ // System.err.println("ray origin inside sphere" ); return true; // ray origin inside sphere } tca = oc.x*dir.x + oc.y*dir.y + oc.z*dir.z; if( tca <= 0.0 ) { // System.err.println("ray points away from sphere" ); return false; // ray points away from sphere } t2hc = rad2 - l2oc + tca*tca; if( t2hc > 0.0 ){ t = tca - Math.sqrt(t2hc); if( t*t <= ((end.x-start.x)*(end.x-start.x)+ (end.y-start.y)*(end.y-start.y)+ (end.z-start.z)*(end.z-start.z))){ position.x = start.x + dir.x*t; position.y = start.y + dir.x*t; position.z = start.z + dir.x*t; position.w = t; return true; // segment hits sphere } } return false; } /** * 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; } double l2oc,rad2,tca,t2hc,mag; Vector3d dir = new Vector3d(); // normalized direction of ray Point3d oc = new Point3d(); // vector from sphere center to ray origin oc.x = center.x - origin.x; oc.y = center.y - origin.y; oc.z = center.z - origin.z; l2oc = oc.x*oc.x + oc.y*oc.y + oc.z*oc.z; // center to origin squared rad2 = radius*radius; if( l2oc < rad2 ){ // System.err.println("ray origin inside sphere" ); return true; // ray origin inside sphere } mag = Math.sqrt(direction.x*direction.x + direction.y*direction.y + direction.z*direction.z); dir.x = direction.x/mag; dir.y = direction.y/mag; dir.z = direction.z/mag; tca = oc.x*dir.x + oc.y*dir.y + oc.z*dir.z; if( tca <= 0.0 ) { // System.err.println("ray points away from sphere" ); return false; // ray points away from sphere } t2hc = rad2 - l2oc + tca*tca; if( t2hc > 0.0 ){ // System.err.println("ray hits sphere" ); return true; // ray hits sphere }else { // System.err.println("ray does not hit sphere" ); return false; } } /** * Returns the position of the intersect point if the ray intersects with * the sphere. * */ boolean intersect(Point3d origin, Vector3d direction, Point3d intersectPoint ) { if( boundsIsEmpty ) { return false; } if( boundsIsInfinite ) { intersectPoint.x = origin.x; intersectPoint.y = origin.y; intersectPoint.z = origin.z; return true; } double l2oc,rad2,tca,t2hc,mag,t; Point3d dir = new Point3d(); // normalized direction of ray Point3d oc = new Point3d(); // vector from sphere center to ray origin oc.x = center.x - origin.x; // XXXX: check if this method is still needed oc.y = center.y - origin.y; oc.z = center.z - origin.z; l2oc = oc.x*oc.x + oc.y*oc.y + oc.z*oc.z; // center to origin squared rad2 = radius*radius; if( l2oc < rad2 ){ // System.err.println("ray origin inside sphere" ); return true; // ray origin inside sphere } mag = Math.sqrt(direction.x*direction.x + direction.y*direction.y + direction.z*direction.z); dir.x = direction.x/mag; dir.y = direction.y/mag; dir.z = direction.z/mag; tca = oc.x*dir.x + oc.y*dir.y + oc.z*dir.z; if( tca <= 0.0 ) { // System.err.println("ray points away from sphere" ); return false; // ray points away from sphere } t2hc = rad2 - l2oc + tca*tca; if( t2hc > 0.0 ){ t = tca - Math.sqrt(t2hc); intersectPoint.x = origin.x + direction.x*t; intersectPoint.y = origin.y + direction.y*t; intersectPoint.z = origin.z + direction.z*t; // System.err.println("ray hits sphere" ); return true; // ray hits sphere }else { // System.err.println("ray does not hit sphere" ); return false; } } /** * 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 ) { double x,y,z,dist; if( boundsIsEmpty ) { return false; } if( boundsIsInfinite ) { return true; } x = point.x - center.x; y = point.y - center.y; z = point.z - center.z; dist = x*x + y*y + z*z; if( dist > radius*radius) return false; else return true; } /** * Tests whether the bounding sphere is empty. A bounding sphere 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 sphere * with a volume of zero is <i>not</i> empty. * @return true if the bounding sphere 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) { double distsq, radsq; BoundingSphere sphere; boolean intersect; 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; double dis = 0.0; double rad_sq = radius*radius; // find the corner closest to the center of sphere if( center.x < box.lower.x ) dis = (center.x-box.lower.x)*(center.x-box.lower.x); else if( center.x > box.upper.x ) dis = (center.x-box.upper.x)*(center.x-box.upper.x); if( center.y < box.lower.y ) dis += (center.y-box.lower.y)*(center.y-box.lower.y); else if( center.y > box.upper.y ) dis += (center.y-box.upper.y)*(center.y-box.upper.y); if( center.z < box.lower.z ) dis += (center.z-box.lower.z)*(center.z-box.lower.z); else if( center.z > box.upper.z ) dis += (center.z-box.upper.z)*(center.z-box.upper.z); return ( dis <= rad_sq ); } else if( boundsObject.boundId == BOUNDING_SPHERE ) { sphere = (BoundingSphere)boundsObject; radsq = radius + sphere.radius; radsq *= radsq; distsq = center.distanceSquared(sphere.center); return (distsq <= radsq); } else if(boundsObject.boundId == BOUNDING_POLYTOPE) { return intersect_ptope_sphere( (BoundingPolytope)boundsObject, this); } else { throw new IllegalArgumentException(J3dI18N.getString("BoundingSphere6")); } } /** * Test for intersection with another bounds object. * @param boundsObjects an array of bounding objects * @return true or false indicating if an intersection occured */ public boolean intersect(Bounds[] boundsObjects) { double distsq, radsq; BoundingSphere sphere; 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){ if( this.intersect( boundsObjects[i])) return true; } else if( boundsObjects[i].boundId == BOUNDING_SPHERE ) { sphere = (BoundingSphere)boundsObjects[i]; radsq = radius + sphere.radius; radsq *= radsq; distsq = center.distanceSquared(sphere.center); if (distsq <= radsq) { return true; } } else if(boundsObjects[i].boundId == BOUNDING_POLYTOPE) { if( this.intersect( boundsObjects[i])) return true; } else { throw new IllegalArgumentException(J3dI18N.getString("BoundingSphere7")); } } return false; } /** * Test for intersection with another bounds object. * @param boundsObject another bounds object * @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 boundsObject, BoundingSphere newBoundSphere) { if((boundsObject == null ) || boundsIsEmpty || boundsObject.boundsIsEmpty) { // Negative volume. newBoundSphere.center.x = newBoundSphere.center.y = newBoundSphere.center.z = 0.0; newBoundSphere.radius = -1.0; newBoundSphere.updateBoundsStates(); return false; } if(boundsIsInfinite && (!boundsObject.boundsIsInfinite)) { newBoundSphere.set(boundsObject); return true; } else if((!boundsIsInfinite) && boundsObject.boundsIsInfinite) { newBoundSphere.set(this); return true; } else if(boundsIsInfinite && boundsObject.boundsIsInfinite) { newBoundSphere.set(this); return true; } else if(boundsObject.boundId == BOUNDING_BOX){ BoundingBox tbox = new BoundingBox(); BoundingBox box = (BoundingBox)boundsObject; if( this.intersect( box) ){ BoundingBox sbox = new BoundingBox( this ); // convert sphere to box sbox.intersect(box, tbox); // insersect two boxes newBoundSphere.set( tbox ); // set sphere to the intersection of 2 boxes 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 if( boundsObject.boundId == BOUNDING_SPHERE ) { BoundingSphere sphere = (BoundingSphere)boundsObject; double dis,t,d2; boolean status; 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) { // Negative volume. newBoundSphere.center.x = newBoundSphere.center.y = newBoundSphere.center.z = 0.0; newBoundSphere.radius = -1.0; status = false;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -