@Override public boolean intersectsSphere(final BoundingSphere bs) { if (!Vector3.isValid(_center) || !Vector3.isValid(bs._center)) { return false; } final Vector3 diff = _compVect1.set(getCenter()).subtractLocal(bs.getCenter()); final double rsum = getRadius() + bs.getRadius(); return (diff.dot(diff) <= rsum * rsum); }
@Override public boolean intersects(final ReadOnlyRay3 ray) { if (!Vector3.isValid(_center)) { return false; } final Vector3 diff = ray.getOrigin().subtract(getCenter(), _compVect1); final double radiusSquared = getRadius() * getRadius(); final double a = diff.dot(diff) - radiusSquared; if (a <= 0.0) { // in sphere return true; } // outside sphere final Vector3 dir = _compVect2.set(ray.getDirection()); final double b = dir.dot(diff); if (b >= 0.0) { return false; } return b * b >= a; }
@Override public IntersectionRecord intersectsWhere(final ReadOnlyRay3 ray) { final Vector3 diff = ray.getOrigin().subtract(getCenter(), _compVect1); final double a = diff.dot(diff) - (getRadius() * getRadius()); double a1, discr, root; if (a <= 0.0) { // inside sphere a1 = ray.getDirection().dot(diff); discr = (a1 * a1) - a; root = Math.sqrt(discr); final double[] distances = new double[] {root - a1}; final Vector3[] points = new Vector3[] { ray.getDirection().multiply(distances[0], new Vector3()).addLocal(ray.getOrigin()) }; return new IntersectionRecord(distances, points); } a1 = ray.getDirection().dot(diff); if (a1 >= 0.0) { // No intersection return null; } discr = a1 * a1 - a; if (discr < 0.0) { return null; } else if (discr >= MathUtils.ZERO_TOLERANCE) { root = Math.sqrt(discr); final double[] distances = new double[] {-a1 - root, -a1 + root}; final Vector3[] points = new Vector3[] { ray.getDirection().multiply(distances[0], new Vector3()).addLocal(ray.getOrigin()), ray.getDirection().multiply(distances[1], new Vector3()).addLocal(ray.getOrigin()) }; final IntersectionRecord record = new IntersectionRecord(distances, points); return record; } final double[] distances = new double[] {-a1}; final Vector3[] points = new Vector3[] { ray.getDirection().multiply(distances[0], new Vector3()).addLocal(ray.getOrigin()) }; return new IntersectionRecord(distances, points); }
/** * 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); } }