/** * Calculates the minimum bounding sphere of 4 points. Used in welzl's algorithm. * * @param O The 1st point inside the sphere. * @param A The 2nd point inside the sphere. * @param B The 3rd point inside the sphere. * @param C The 4th point inside the sphere. * @see #calcWelzl(java.nio.FloatBuffer) */ private void setSphere(final Vector3 O, final Vector3 A, final Vector3 B, final Vector3 C) { final Vector3 a = A.subtract(O, null); final Vector3 b = B.subtract(O, null); final Vector3 c = C.subtract(O, null); final double Denominator = 2.0 * (a.getX() * (b.getY() * c.getZ() - c.getY() * b.getZ()) - b.getX() * (a.getY() * c.getZ() - c.getY() * a.getZ()) + c.getX() * (a.getY() * b.getZ() - b.getY() * a.getZ())); if (Denominator == 0) { _center.set(0, 0, 0); setRadius(0); } else { final Vector3 o = a.cross(b, null) .multiplyLocal(c.lengthSquared()) .addLocal(c.cross(a, null).multiplyLocal(b.lengthSquared())) .addLocal(b.cross(c, null).multiplyLocal(a.lengthSquared())) .divideLocal(Denominator); setRadius(o.length() * radiusEpsilon); O.add(o, _center); } }
/** * Calculates the minimum bounding sphere of 3 points. Used in welzl's algorithm. * * @param O The 1st point inside the sphere. * @param A The 2nd point inside the sphere. * @param B The 3rd point inside the sphere. * @see #calcWelzl(java.nio.FloatBuffer) */ private void setSphere(final Vector3 O, final Vector3 A, final Vector3 B) { final Vector3 a = A.subtract(O, null); final Vector3 b = B.subtract(O, null); final Vector3 acrossB = a.cross(b, null); final double Denominator = 2.0 * acrossB.dot(acrossB); if (Denominator == 0) { _center.set(0, 0, 0); setRadius(0); } else { final Vector3 o = acrossB .cross(a, null) .multiplyLocal(b.lengthSquared()) .addLocal(b.cross(acrossB, null).multiplyLocal(a.lengthSquared())) .divideLocal(Denominator); setRadius(o.length() * radiusEpsilon); O.add(o, _center); } }
/** * <code>merge</code> combines this sphere with a second bounding sphere. This new sphere contains * both bounding spheres and is returned. * * @param volume the sphere to combine with this sphere. * @return a new sphere */ @Override public BoundingVolume merge(final BoundingVolume volume) { if (volume == null) { return this; } switch (volume.getType()) { case Sphere: { final BoundingSphere sphere = (BoundingSphere) volume; final double temp_radius = sphere.getRadius(); final ReadOnlyVector3 tempCenter = sphere.getCenter(); final BoundingSphere rVal = new BoundingSphere(); return merge(temp_radius, tempCenter, rVal); } case AABB: { final BoundingBox box = (BoundingBox) volume; final Vector3 radVect = new Vector3(box.getXExtent(), box.getYExtent(), box.getZExtent()); final Vector3 tempCenter = box._center; final BoundingSphere rVal = new BoundingSphere(); return merge(radVect.length(), tempCenter, rVal); } case OBB: { final OrientedBoundingBox box = (OrientedBoundingBox) volume; final BoundingSphere rVal = (BoundingSphere) this.clone(null); return rVal.mergeLocalOBB(box); } default: return null; } }