161 lines
5.1 KiB
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()
|
|
);
|
|
}
|
|
} |