TDT4100/src/main/java/stateandbehavior/Rectangle.java

161 lines
5.1 KiB
Java

package stateandbehavior;
import java.util.Arrays;
public class Rectangle {
private int[] minPoint;
private int[] maxPoint;
public Rectangle() {
this.minPoint = (new int[] {});
this.maxPoint = (new int[] {});
}
/**
* returnerer henholdsvis x- og y-koordinatene til punktet med
* lavest (x,y)-verdier som er inneholdt i dette rektanglet. Dersom dette rektanglet er tomt, så skal 0 returneres.
*/
public int getMinX() {
return this.isEmpty() ? 0 : this.minPoint[0];
}
/**
* Se {@link #getMinX() getMinX()}
*/
public int getMinY() {
return this.isEmpty() ? 0 : this.minPoint[1];
}
/**
* returnerer henholdsvis x- og y-koordinatene til punktet med høyest (x,y)-verdier som er inneholdt i dette rektanglet. Dersom dette rektanglet er tomt, så skal 0 returneres.
*/
public int getMaxX() {
return this.isEmpty() ? 0 : this.maxPoint[0];
}
/**
* Se {@link #getMaxX() getMaxX()}
*/
public int getMaxY() {
return this.isEmpty() ? 0 : this.maxPoint[1];
}
/** returnerer henholdsvis bredden og høyden til rektanglet. Begge skal returnere 0, dersom dette rektanglet er tomt. */
public int getWidth() {
if (this.isEmpty()) return 0;
return this.maxPoint[0] - this.minPoint[0] + 1;
}
public int getHeight() {
if (this.isEmpty()) return 0;
return this.maxPoint[1] - this.minPoint[1] + 1;
}
/** returnerer true om rektanglet er tomt, dvs. om bredden og/eller høyden er 0. */
public boolean isEmpty(){
return this.minPoint.length == 0;
}
/** returnerer true om punktet (x,y) er inneholdt i dette rektanglet, og false ellers. */
public boolean contains(int x, int y) {
if (this.isEmpty()) return false;
return Arrays.asList(
(this.maxPoint[0] >= x),
(this.maxPoint[1] >= y),
(this.minPoint[0] <= x),
(this.minPoint[1] <= y))
.stream()
.allMatch(b -> b);
}
/** returnerer true om hele rect, dvs. alle punktene i rect, er inneholdt i dette rektanglet, og false ellers. Dersom rect er tomt, så skal false returneres. */
public boolean contains(Rectangle rect) {
if (rect.isEmpty()) return false;
return this.contains(rect.getMaxX(), rect.getMaxY())
&& this.contains(rect.getMinX(), rect.getMinY());
}
/** utvider (om nødvendig) dette rektanglet slik at det (akkurat) inneholder punktet (x,y). Etter kallet skal altså contains(x, y) returnere true. Returnerer true om dette rektanglet faktisk ble endret, ellers false. */
public boolean add(int x, int y) {
if (this.isEmpty()) {
this.maxPoint = (new int[] {x, y});
this.minPoint = (new int[] {x, y});
return true;
}
boolean wasChanged = false;
if (x > this.maxPoint[0]) {
this.maxPoint[0] = x;
wasChanged = true;
}
if (y > this.maxPoint[1]) {
this.maxPoint[1] = y;
wasChanged = true;
}
if (x < this.minPoint[0]) {
this.minPoint[0] = x;
wasChanged = true;
}
if (y < this.minPoint[1]) {
this.minPoint[1] = y;
wasChanged = true;
}
return wasChanged;
}
/** utvider (om nødvendig) dette rektanglet slik at det (akkurat) inneholder hele rect-argumentet. Returnerer true om dette rektanglet faktisk ble endret, ellers false. Dersom rect er tomt, så skal dette rektanglet ikke endres. */
public boolean add(Rectangle rect) {
boolean addedp1 = this.add(rect.getMaxX(), rect.getMaxY());
boolean addedp2 = this.add(rect.getMinX(), rect.getMinY());
return (addedp1 || addedp2);
}
/** returnerer et nytt Rectangle-objekt som tilsvarer kombisjonen av dette rektanglet og rect-argumentet. Alle punktene som finnes i ett av rektanglene skal altså være inneholdt i rektanglet som returneres. */
public Rectangle union(Rectangle rect) {
Rectangle result = new Rectangle();
result.add(this);
result.add(rect);
return result;
}
/** returnerer et nytt Rectangle-objekt som tilsvarer overlappet mellom dette rektanglet og rect-argumentet. Alle punktene som finnes i begge rektanglene skal altså være inneholdt i rektanglet som returneres. */
public Rectangle intersection(Rectangle rect) {
if (this.intersects(rect)) {
int maxX = Math.max(this.minPoint[0], rect.getMinX());
int maxY = Math.max(this.minPoint[1], rect.getMinY());
int minX = Math.min(this.maxPoint[0], rect.getMaxX());
int minY = Math.min(this.maxPoint[1], rect.getMaxY());
Rectangle result = new Rectangle();
result.add(minX, minY);
result.add(maxX, maxY);
return result;
} else {
return new Rectangle();
}
}
/** returnerer true om dette rektanglet og rect-argumentet overlapper, dvs. om det finnes ett eller flere punkter som er inneholdt i begge disse rektanglene. */
public boolean intersects(Rectangle rect) {
if (this.isEmpty() || rect.isEmpty()) return false;
return !((this.minPoint[0] > rect.getMaxX() || rect.getMinX() > this.maxPoint[0])
&& (this.minPoint[1] > rect.getMaxY() || rect.getMinY() > this.maxPoint[1]));
}
@Override
public String toString() {
if (this.isEmpty()) return "Empty";
return String.format("(%d, %d), (%d, %d), [%d x %d]",
minPoint[0],
minPoint[1],
maxPoint[0],
maxPoint[1],
getWidth(),
getHeight()
);
}
}