Informatik Java Rechtecke vergleichen?
Ein achsenparalleles Rechteck ist durch die Koordinaten von zwei gegenüberliegenden Eckpunkten P(px, py) und Q(qx, qy) bestimmt. Schreiben Sie ein Java Programm Rectangles, das die Lage zweier gegebener achsenparalleler Rechtecke zueinander in einem Koordinatensystem bestimmt und folgende Fälle unterscheidet:
disjoint
Die Schnittmenge der beiden Rechtecke ist leer, sie haben keinen gemeinsamen Punkt. same Die Lage und Größe beider Rechtecke sind gleich.
contained
Der Durchschnitt der beiden Rechtecke entspricht genau einem der beiden Rechtecke. Alle Punkte des einen Rechtecks sind auch in dem anderen enthalten, aber nicht umgekehrt.
aligned
Der Durchschnitt der beiden Rechtecke ergibt eine Linie. Alle gemeinsamen Punkte liegen auf einer Linie mit einer Länge > 0.
touching
Der Durchschnitt der beiden Rechtecke ergibt einen Punkt. Beide Rechtecke haben genau einen gemeinsamen Punkt.
intersecting
Der Durchschnitt der beiden Rechtecke ergibt ein weiteres Rechteck mit einem Flächeninhalt > 0. Ihr Programm liest acht Argumente von der Kommandozeile ein.
Dies sind die beiden Koordinaten P(px, py) und Q(qx, qy) des ersten Rechtecks sowie die Koordinaten S(sx, sy) und T(tx, ty) des zweiten Rechtecks. Berechnen Sie die Lage der beiden gegebenen Rechtecke zueinander und geben Sie das zugehörige Schlüsselwort entsprechend obiger Liste aus.
Beispiel: Für die beiden Rechtecke P(2, 2), Q(7, 5) und S(3, 4), T(0, 6) liefert der Aufruf
C:\> java Rectangles 2 2 7 5 3 4 0 6
intersecting
Ich möchte es mit if befehl machen habe aber keinen plan wie ich die miteinander vergleichen soll :D
2 Antworten
Hallo InformatikNoob,
same könnte doch so aussehen:
public boolean same(Rect other) {
return (px == other.getPx() && py == other.getPy()) || (px == other.getQx() && py == other.getQy());
}
Man muss beachten, dass die beiden Eckpunkte eines Rechtecks ausgetauscht werden können und das Rechteck trotzdem deckungsgleich bleibt. Daher rührt der oder Teil.
Ansonsten könnte man natürlich seine Rechteckklasse entsprechend so anpassen, dass gleiche Rechtecke auch mit gleichen px, py, qx, qy abgespeichert werden.
Den Eckentausch prüfe ich auch direkt im ersten Unit-Test. Bei der Anzahl der möglichen/nötigen Tests, sollte man wohl auf parametrisierte Tests ausweichen, da es doch sehr viele werden.
Als Basis kannst Du aber von dem hier ausgehen und sinnvoll ergänzen, bzw. auf Parameter umstellen:
import org.junit.Test;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class RectTest {
@Test
public void same_rect_should_return_true_on_switched_edges() {
Rect rectA = new Rect(1, 3, 4, 5);
Rect rectB = new Rect(4, 5, 1, 3);
boolean result = rectA.same(rectB);
assertTrue(result);
}
@Test
public void same_rect_should_return_true_on_px_smaller_qx_and_py_smaller_qy() {
Rect rectA = new Rect(1, 3, 4, 5);
Rect rectB = new Rect(1, 3, 4, 5);
boolean result = rectA.same(rectB);
assertTrue(result);
}
@Test
public void same_rect_should_return_true_on_px_greater_qx_and_py_smaller_qy() {
Rect rectA = new Rect(5, 3, 4, 5);
Rect rectB = new Rect(5, 3, 4, 5);
boolean result = rectA.same(rectB);
assertTrue(result);
}
@Test
public void same_rect_should_return_true_on_px_smaller_qx_and_py_greater_qy() {
Rect rectA = new Rect(1, 5, 4, 3);
Rect rectB = new Rect(1, 5, 4, 3);
boolean result = rectA.same(rectB);
assertTrue(result);
}
@Test
public void same_rect_should_return_true_on_px_greater_qx_and_py_greater_qy() {
Rect rectA = new Rect(5, 5, 4, 3);
Rect rectB = new Rect(5, 5, 4, 3);
boolean result = rectA.same(rectB);
assertTrue(result);
}
@Test
public void same_rect_should_return_false_on_px_not_equals() {
Rect rectA = new Rect(6, 5, 4, 3);
Rect rectB = new Rect(5, 5, 4, 3);
boolean result = rectA.same(rectB);
assertFalse(result);
}
@Test
public void same_rect_should_return_false_on_py_not_equals() {
Rect rectA = new Rect(5, 5, 4, 3);
Rect rectB = new Rect(5, 4, 4, 3);
boolean result = rectA.same(rectB);
assertFalse(result);
}
//add more tests
}
Eine Rect-Klasse hast Du ja sicher schon, hier ist trotzdem noch meine Version:
public class Rect {
private int px;
private int py;
private int qx;
private int qy;
public Rect(int px, int py, int qx, int qy) {
this.px = px;
this.py = py;
this.qx = qx;
this.qy = qy;
}
public int getPx() {
return px;
}
public int getPy() {
return py;
}
public int getQx() {
return qx;
}
public int getQy() {
return qy;
}
public boolean same(Rect other) {
return (px == other.getPx() && py == other.getPy()) || (px == other.getQx() && py == other.getQy());
}
}
Wie Du siehst werden keine Punkte getauscht, oder sonstige Überprüfungen vorgenommen. Wenn sich alle Punkte überschneiden, dann spricht man sicher nicht mehr von einem Rechteck. Eine Linie ist auch kein Rechteck. Alles Prüfungen, die noch nicht implementiert sind.
Gruß
In jedem mir bekannten Framework gibt es eine Funktion "IntersectRect" (ggfs. mit anderer Schreibweise).
Du brauchst die nur auszuführen und das Ergebnis mit den beiden ursprünglichen Rechtecken zu vergleichen.