org.pepsoft.util.Box Maven / Gradle / Ivy
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package org.pepsoft.util;
import java.awt.*;
/**
* A rectangular three dimensional volume, defined by two corners, the corner
* with the lowest x, y and z coordinates being inclusive and the opposite
* corner being exclusive.
*
* @author pepijn
*/
public final class Box implements Cloneable {
public Box() {
// Do nothing
}
public Box(int x1, int x2, int y1, int y2, int z1, int z2) {
this.x1 = x1;
this.y1 = y1;
this.z1 = z1;
this.x2 = x2;
this.y2 = y2;
this.z2 = z2;
normalise();
}
public int getX1() {
return x1;
}
public void setX1(int x1) {
this.x1 = x1;
}
public int getX2() {
return x2;
}
public void setX2(int x2) {
this.x2 = x2;
}
public int getY1() {
return y1;
}
public void setY1(int y1) {
this.y1 = y1;
}
public int getY2() {
return y2;
}
public void setY2(int y2) {
this.y2 = y2;
}
public int getZ1() {
return z1;
}
public void setZ1(int z1) {
this.z1 = z1;
}
public int getZ2() {
return z2;
}
public void setZ2(int z2) {
this.z2 = z2;
}
/**
* Get the size of the box along the X axis.
*
* @return The size of the box along the X axis.
*/
public int getWidth() {
return Math.abs(x2 - x1);
}
/**
* Get the size of the box along the Y axis.
*
* @return The size of the box along the Y axis.
*/
public int getLength() {
return Math.abs(y2 - y1);
}
/**
* Get the size of the box along the Z axis.
*
* @return The size of the box along the Z axis.
*/
public int getHeight() {
return Math.abs(z2 - z1);
}
/**
* Get the volume of the box.
*
* @return The volume of the box.
*/
public int getVolume() {
return getWidth() * getLength() * getHeight();
}
/**
* Get the total surface area of the box.
*
* @return The total surface area of the box.
*/
public int getSurface() {
int width = getWidth(), length = getLength(), height = getHeight();
return width * height * 2
+ length * height * 2
+ width * length * 2;
}
public void translate(int dx, int dy, int dz) {
x1 += dx;
x2 += dx;
y1 += dy;
y2 += dy;
z1 += dz;
x2 += dz;
}
/**
* Extends this box so that it encompasses the other box
*
* @param box The box to encompass.
*/
public void encompass(Box box) {
normalise();
box.normalise();
if (box.x1 < x1) {
x1 = box.x1;
}
if (box.x2 > x2) {
x2 = box.x2;
}
if (box.y1 < y1) {
y1 = box.y1;
}
if (box.y2 > y2) {
y2 = box.y2;
}
if (box.z1 < z1) {
z1 = box.z1;
}
if (box.z2 > z2) {
z2 = box.z2;
}
}
/**
* Sets this box to the intersection of it and the specified box; in other
* words to the volume encompassed by both boxes.
*
* If the boxes don't intersect, the x2, y2 and z2 coordinates of this
* box will be made equal to the x1, y1 and z1 coordinates so that it
* becomes empty.
*
* @param box The box to intersect this box with.
*/
public void intersect(Box box) {
normalise();
box.normalise();
if ((box.x1 >= x2) || (box.x2 <= x1) || (box.y1 >= y2) || (box.y2 <= y1) || (box.z1 >= z2) || (box.z2 <= z1)) {
// The boxes don't intersect
x2 = x1;
y2 = y1;
z2 = z1;
} else {
if (box.x1 > x1) {
x1 = box.x1;
}
if (box.x2 > x2) {
x2 = box.x2;
}
if (box.y1 > y1) {
y1 = box.y1;
}
if (box.y2 > y2) {
y2 = box.y2;
}
if (box.z1 > z1) {
z1 = box.z1;
}
if (box.z2 > z2) {
z2 = box.z2;
}
}
}
public boolean isEmpty() {
return (x1 == x2) && (y1 == y2) && (z1 == z2);
}
public boolean contains(int x, int y, int z) {
return (x >= x1) && (x < x2) && (y >= y1) && (y < y2) && (z >= z1) && (z < z2);
}
public boolean containsXY(int x, int y) {
return (x >= x1) && (x < x2) && (y >= y1) && (y < y2);
}
public Rectangle getFootPrint() {
normalise();
return new Rectangle(x1, y1, x2 - x1, y2 - y1);
}
/**
* Expand the box by a particular amount in every direction.
*
* @param delta The delta by which to move every face of the box outwards.
*/
public void expand(int delta) {
normalise();
x1 -= delta;
x2 += delta;
y1 -= delta;
y2 += delta;
z1 -= delta;
z2 += delta;
}
@Override
public String toString() {
return "[" + x1 + "," + y1 + "," + z1 + " -> " + x2 + "," + y2 + "," + z2 + "]";
}
@Override
public Box clone() {
try {
return (Box) super.clone();
} catch (CloneNotSupportedException e) {
throw new InternalError();
}
}
/**
* Normalises the coordinates such that coordinate 1 is always lower than
* coordinate 2.
*/
private void normalise() {
int tmp;
if (x1 > x2) {
tmp = x1;
x1 = x2;
x2 = tmp;
}
if (y1 > y2) {
tmp = y1;
y1 = y2;
y2 = tmp;
}
if (z1 > z2) {
tmp = z1;
z1 = z2;
z2 = tmp;
}
}
private int x1, y1, z1, x2, y2, z2;
}