package spimedb.util.geom; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import java.util.List; import static java.lang.Math.abs; /** * Created by me on 6/14/15. */ @JsonSerialize public interface BB extends XYZ, Shape3D { // public BB() { // super(); // } // // public BB(XYZ v) { // super(v); // } // // public BB(Vec3D center, Vec3D radius) { // super(center); // this.extent = (radius); // } // public BB(Vec3D center, float radius) { // super(center); // this.extent = new Vec3D(radius,radius,radius); // } /** * Creates a new instance from two vectors specifying opposite corners of * the box * * @param min * first corner point * @param max * second corner point * @return new AABB with centre at the half point between the 2 input * vectors */ static AABB fromMinMax(Vec3D min, Vec3D max) { Vec3D a = Vec3D.min(min, max); Vec3D b = Vec3D.max(min, max); return new AABB(a.interpolateTo(b, 0.5f), b.sub(a).scaleSelf(0.5f)); } /** * Factory method, computes & returns the bounding box for the given list of * points. * * @param points * @return bounding rect */ static BB getBoundingBox(List<? extends XYZ> points) { if (points == null || points.size() == 0) { return null; } XYZ first = points.get(0); Vec3D min = new Vec3D(first); Vec3D max = new Vec3D(first); int n = points.size(); if (n > 1) { for (int i = 1; i < n; i++) { XYZ p = points.get(i); min.minSelf(p); max.maxSelf(p); } } return fromMinMax(min, max); } default boolean containsPoint(XYZ p) { return p.isInAABB(this); } default Sphere getBoundingSphere() { return new Sphere(this, getExtents().magnitude()); } XYZ getExtents(); /** * Checks if the box intersects the passed in one. * * @param box * box to check * @return true, if boxes overlap */ default boolean intersectsBox(final BB box) { XYZ extent = getExtents(); XYZ bext = box.getExtents(); return (abs(box.x() - x()) <= (extent.x() + bext.x())) && (abs(box.y() - y()) <= (extent.y() + bext.y())) && (abs(box.z() - z()) <= (extent.z() + bext.z())); } default boolean intersectsSphere(Sphere s) { return intersectsSphere(s, s.radius); } /** * @param c * sphere centre * @param r * sphere radius * @return true, if AABB intersects with sphere */ default boolean intersectsSphere(Vec3D c, float r) { float s, d = 0; // find the square of the distance // from the sphere to the box if (c.x < minX()) { s = c.x - minX(); d = s * s; } else if (c.x > maxX()) { s = c.x - maxX(); d += s * s; } if (c.y < minY()) { s = c.y - minY(); d += s * s; } else if (c.y > maxY()) { s = c.y - maxY(); d += s * s; } if (c.z < minZ()) { s = c.z - minZ(); d += s * s; } else if (c.z > maxZ()) { s = c.z - maxZ(); d += s * s; } return d <= r * r; } default boolean contains(final XYZ v) { final float x = v.x(); if (x!=x) return false; if (x < minX() || x > maxX()) { return false; } final float y = v.y(); if (y < minY() || y > maxY()) { return false; } final float z = v.z(); return !(z < minZ() || z > maxZ()); } float minX();// { return x - extent.x(); } float maxX();// { return x + extent.x(); } float minY();// { return y - extent.y(); } float maxY();// { return y + extent.y(); } float minZ();// { return z - extent.z(); } float maxZ();// { return z + extent.z(); } }