package rtree; /** * 3D Axis Aligned Bounding Box * @author Colonel32 */ public class AABB implements BoundedObject { public int minX, minY, minZ; public int maxX, maxY, maxZ; public AABB() { minX = minY = minZ = 0; maxX = maxY = maxZ = 0; } public void setMinCorner(int px, int py, int pz) { minX = px; minY = py; minZ = pz; } public void setMaxCorner(int px, int py, int pz) { maxX = px; maxY = py; maxZ = pz; } public boolean contains(int px, int py, int pz) { return px >= minX && px <= maxX && py >= minY && py <= maxY && pz >= minZ && pz <= maxZ; } public boolean overlaps(AABB other) { if(minX > other.maxX) return false; if(maxX < other.minX) return false; if(minY > other.maxY) return false; if(maxY < other.minY) return false; if(minZ > other.maxZ) return false; if(maxZ < other.minZ) return false; return true; } /** * Returns the amount of overlap between 2 AABBs. Result will be negative if they * do not overlap. */ public int getOverlap(AABB other) { int overlapx = (maxX - minX +other.maxX - other.minX) - Math.abs(minX+maxX-other.minX-other.minX); int overlapy = (maxY - minY +other.maxY - other.minY) - Math.abs(minX+maxY-other.minY-other.minY); int overlapz = (maxZ - minZ +other.maxZ - other.minZ) - Math.abs(minX+maxZ-other.minZ-other.minZ); return Math.max(overlapx, Math.max(overlapy, overlapz)); } /** * Returns the amount that other will need to be expanded to fit this. */ public int expansionNeeded(AABB other) { int total = 0; if(other.minX < minX) total += minX - other.minX; if(other.maxX > maxX) total += other.maxX - maxX; if(other.minY < minY) total += minY - other.minY; if(other.maxY > maxY) total += other.maxY - maxY; if(other.minZ < minZ) total += minZ - other.minZ; if(other.maxZ > maxZ) total += other.maxZ - maxZ; return total; } /** * Computes an AABB that contains both this and other and stores it in this. * @return this */ public AABB merge(AABB other) { minX = Math.min(minX, other.minX); maxX = Math.max(maxX, other.maxX); minY = Math.min(minY, other.minY); maxY = Math.max(maxY, other.maxY); minZ = Math.min(minZ, other.minZ); maxZ = Math.max(maxZ, other.maxZ); return this; } public int getVolume() { return (maxX - minX) * (maxY - minY) * (maxZ - minZ); } public AABB clone() { AABB clone = new AABB(); clone.minX = minX; clone.minY = minY; clone.minZ = minZ; clone.maxX = maxX; clone.maxY = maxY; clone.maxZ = maxZ; return clone; } public void cloneInto(AABB target) { target.minX = minX; target.minY = minY; target.minZ = minZ; target.maxX = maxX; target.maxY = maxY; target.maxZ = maxZ; } public boolean equals(AABB other) { return minX == other.minX && maxX == other.maxX && minY == other.minY && maxY == other.maxY && minZ == other.minZ && maxZ == other.maxZ; } public AABB getBounds() { return this; } public String toString() { return String.format("(%1$d,%2$d,%3$d):(%4$d,%5$d,%6$d)", minX, minY, minZ, maxX, maxY, maxZ); } }