/** * Gets the sphere radius-squared. * @return the radius-squared. */ public double getRadiusSquared() { Check.state(!isEmpty(),"bounding sphere is not empty"); return _r*_r; }
/** * Gets the sphere radius. * @return the radius. */ public double getRadius() { Check.state(!isEmpty(),"bounding sphere is not empty"); return _r; }
/** * Determines whether this sphere contains a point with specified coordinates. * @param x the point x coordinate. * @param y the point y coordinate. * @param z the point z coordinate. * @return true, if this sphere contains the point; false, otherwise. */ public boolean contains(double x, double y, double z) { if (isEmpty()) return false; if (isInfinite()) return true; double dx = _x-x; double dy = _y-y; double dz = _z-z; double rs = _r*_r; return dx*dx+dy*dy+dz*dz<=rs; }
/** * Expands this sphere to include the point with specified coordinates. * Changes only the radius, if necessary, not the center of this sphere. * @param x the x coordinate of the point. * @param y the y coordinate of the point. * @param z the z coordinate of the point. */ public void expandRadiusBy(double x, double y, double z) { if (!isInfinite()) { if (!isEmpty()) { double dx = x-_x; double dy = y-_y; double dz = z-_z; double d = sqrt(dx*dx+dy*dy+dz*dz); if (d>_r) _r = d; } else { _x = x; _y = y; _z = z; _r = 0.0; } } }
/** * Expands this sphere to include the point with specified coordinates. * Adjusts the sphere center to minimize any increase in radius. * @param x the x coordinate of the point. * @param y the y coordinate of the point. * @param z the z coordinate of the point. */ public void expandBy(double x, double y, double z) { if (!isInfinite()) { if (!isEmpty()) { double dx = x-_x; double dy = y-_y; double dz = z-_z; double d = sqrt(dx*dx+dy*dy+dz*dz); if (d>_r) { double dr = 0.5*(d-_r); double ds = dr/d; _x += dx*ds; _y += dy*ds; _z += dz*ds; _r += dr; } } else { _x = x; _y = y; _z = z; _r = 0.0; } } }
/** * Expands this sphere to include the specified bounding sphere. * Changes only the radius, if necessary, not the center of this sphere. * @param bs the bounding sphere. */ public void expandRadiusBy(BoundingSphere bs) { if (!isInfinite()) { if (!bs.isInfinite()) { if (!bs.isEmpty()) { if (!isEmpty()) { double dx = bs._x-_x; double dy = bs._y-_y; double dz = bs._z-_z; double d = sqrt(dx*dx+dy*dy+dz*dz); double r = d+bs._r; if (r>_r) _r = r; } else { _r = bs._r; _x = bs._x; _y = bs._y; _z = bs._z; } } } else { setInfinite(); } } }
/** * Gets the sphere center. * @return the center. */ public Point3 getCenter() { Check.state(!isEmpty(),"bounding sphere is not empty"); Check.state(!isInfinite(),"bounding sphere is not infinite"); return new Point3(_x,_y,_z); }
/** * Expands this box to include the specified bounding sphere. * @param bs the bounding sphere. */ public void expandBy(BoundingSphere bs) { if (!bs.isInfinite()) { if (!bs.isEmpty()) { double r = bs.getRadius(); Point3 c = bs.getCenter(); double x = c.x; double y = c.y; double z = c.z; if (_xmin>x-r) _xmin = x-r; if (_ymin>y-r) _ymin = y-r; if (_zmin>z-r) _zmin = z-r; if (_xmax<x+r) _xmax = x+r; if (_ymax<y+r) _ymax = y+r; if (_zmax<z+r) _zmax = z+r; } } else { setInfinite(); } }
double ymax = pmax.y; double zmax = pmax.z; if (!isEmpty()) { for (int i=0; i<8; ++i) { double x = ((i&1)==0)?xmin:xmax;
/** * Determines whether the view frustrum intersects the bounding sphere * of the specified node. * @param node the node with a bounding sphere. * @return true, if the view frustum intersects the bounding sphere; * false, otherwise. */ public boolean frustumIntersectsSphereOf(Node node) { if (_active!=0) { // if at least one frustum plane is active, ... BoundingSphere bs = node.getBoundingSphere(false); if (bs.isEmpty()) return false; if (bs.isInfinite()) return true; Point3 c = bs.getCenter(); double r = bs.getRadius(); double s = -r; for (int i=0,plane=1; i<6; ++i,plane<<=1) { // for all six planes if ((_active&plane)!=0) { // if plane is active double d = _planes[i].distanceTo(c); // distance from center if (d<s) { // if sphere is entirely outside (below plane) return false; // no intersection } else if (d>r) { // else if sphere is entirely above plane _active ^= plane; // need not test this plane again } } } } return true; }
if (bs.isEmpty()) return false; if (bs.isInfinite())
double ymax = pmax.y; double zmax = pmax.z; if (!isEmpty()) { for (int i=0; i<8; ++i) { double x = ((i&1)==0)?xmin:xmax;
public void testSphereExpand() { int ntrial = 100; for (int itrial=0; itrial<ntrial; ++itrial) { BoundingSphere bs = new BoundingSphere(); assertTrue(bs.isEmpty()); int nexpand = 100; for (int iexpand=0; iexpand<nexpand; ++iexpand) { Point3 p = randomPoint3(); Point3 q = randomPoint3(); BoundingBox bb = new BoundingBox(p,q); if (randomDouble()>0.5) { bs.expandBy(bb); } else { bs.expandRadiusBy(bb); } assertTrue(!bs.isEmpty()); int npoint=100; for (int ipoint=0; ipoint<npoint; ++ipoint) { Point3 r = randomPoint3(); if (bb.contains(r)) assertTrue(bs.contains(r)); } } } }
if (!bs.isEmpty() && !bs.isInfinite()) { double r = bs.getRadius(); Point3 c = bs.getCenter();