# Fehler in meiner Klasse Rechteck



## Jariel (4. Dez 2010)

Ich muss eine Klasse Rechteck mit bestimmten Methoden (die Aufgabenbeschreibung habe ich als Kommentar bei den jeweiligen Methoden hinzugefügt) schreiben.

Dann gibt es eine vorgegebene Testklasse, die meine Klasse Rechteck testet, mit den Methoden Berechnungen anstellt und dann mehrere Rechtecke grafisch mit unterschiedlichen Farben ausgibt, allerdings kommen bei mir keine Rechtecke heraus, sondern nur die Farbe des Grafikfensters ändert sich. Also muss in meinem Code ein Fehler drin sein (Java selbst meldet keine Fehler).

Ansonsten gibt es die vorgegebene Klasse Punkt die mir bei der Erstellung des Rechteckes helfen soll und die ich benutzen hat, die Klasse hat dabei folgende Methoden:
getX() liefert die X-Koordinate des Punktes.
getY() liefert die Y-Koordinate des Punktes.
move(x,y) verschiebt den Punkt um x und y.

Unten ist der aktualisierte Code meiner Klasse Rechteck


----------



## Marco13 (4. Dez 2010)

Die Klassen enthält schrecklich viele redundante Informationen, und Redundanz ist redundant, weil sie redundant ist (da ist das wie mit den Tautologien).

Ein Rechteck braucht 
- Linker Oberer + Rechter Unterer Punkt *ODER*
- Linker Oberer + (width,height) *ODER*
- Linker Oberer + Center *ODER*
- Irgendeine andere Kombination, aus der sich immer alle anderen Werte berechnen lassen.

Schreib' das ganze mal so um, dass das Rechteck nur
- Linker Oberer + (width,height)
enthält, und die anderen Sachen in den jeweiligen get-Methoden daraus berechnet werden

Was der Code im Konstruktor
public Rechteck(Punkt a, Punkt b) {
machen soll, hat sich mir nicht erschlossen, ist aber definitiv viel zu kompliziert. Wenn erstmal alles überflüssige rausfällt, wird das vermutlich auch einfacher....

Ansonsten hilft vielleicht sowas wie

```
public String toString()
{
    return "Rechteck (upperLeft="+upperLeft+",size="+width+","+height+")";
}
```
und dann ein
System.out.println("Erstellt: "+this);
am Ende jedes Konstuktors, um zu sehen, was er da eigentlich macht...


----------



## Jariel (4. Dez 2010)

Ich habe jetzt den Mittelpunkt herausgekürzt, den rechten unteren Punkt habe ich noch dringelassen weil es sich meiner Meinung nach angeboten hat ihn zusammen mit dem linkeren oberen Punkt im Konstruktor zu bestimmen.

Zur Erklärung nochmal was ich im Konstruktor public Rechteck(Punkt a, Punkt b) gemacht habe:

Punkt a und b sind ja die gegenüberliegenden Eckpunkte, also habe ich um die Breite des Rechtecks zu bekommen den x Wert von Punkt a subtrahiert vom x Wert von Punkt b. Damit kein negativer Wert herauskommt habe ich das ganze mit der komisch aussehenden Formel gemacht, das ist eigentlich nichts anderes als dass ich das ganze in Betragsstriche setze.
Das selbe analog für die Höhe.

Danach habe ich die linke obere Ecke gesucht. Da die linke obere Ecke die kleinsten Koordinaten hat (Der Ursprung der Java Koordinaten ist links oben, von den Aufgabenerstellern als Hinweis gegeben), habe ich mit if versucht die Ecke mit der kleinsten Summe der Koordinaten zu finden.

Irgendwo muss aber ein Fehler drin sein weil nicht das rauskommt was rauskommen soll, wo könnte der liegen?

Hier der aktualisierte Code:


```
-
```


----------



## Jariel (4. Dez 2010)

Nochmal gekürzt (um LowerRight) sodass nur noch die 3 nötigen Variablen height, width und UpperLeft da sind, aber den Fehler kann ich nicht entdecken:


```
-
```


----------



## Marco13 (5. Dez 2010)

Ja, ich meinte, dass der Konstruktor (jetzt) wohl auch so aussehen könnte

```
public Rechteck(Punkt a, Punkt b) 
{
    this.width = Math.abs(a.getX() - b.getX());
    this.height = Math.abs(a.getY() - b.getY());
    this.UpperLeft = new Punkt(
        Math.min(a.getX(), b.getX()), 
        Math.min(a.getY(), b.getY()));
    }
}
```

Es ist jetzt aber immernoch schwer zu sagen, was genau falsch ist, da die Symptombeschreibung für die Fehlersuche ziemlich dünn ist...


----------



## Jariel (5. Dez 2010)

Stimmt so ist es übersichtlicher. Einige kleinere Fehler habe ich in den Methoden schon entdeckt und behoben, jetzt taucht, sobald ich die Testklasse ablaufen lasse, zumindest einmal ein Rechteck auf. Aber danach sollten noch mehr auftauchen, tun sie aber nicht, ich vermute dass wegen Fehler in meinen Methoden die Rechtecke ausserhalb des Java Fensters berechnet werden, also die Koordinaten nicht stimmen.



```
-
```


----------



## Marco13 (5. Dez 2010)

Poste am besten auch die Testklasse


----------



## Jariel (6. Dez 2010)

Hallo, Abgabetermin ist vorbei, habs leider nicht hinbekommen trotzdem danke

hier die Musterlösung:


```
public class Rechteck {
	// Es gibt viele MÃ¶glichkeiten, wir wÃ¤hlen als Attribute:
	private Punkt middle; // Mittelpunkt des Rechtecks
	private int halfwidth; // Halbe Breite des Rechtecks
	private int halfheight; // Halbe HÃ¶he des Rechtecks
	// Halbe Breite und HÃ¶he erleichtert uns das Ausrechnen der Ecken.
	
	/**
	 * Erstellt das Rechteck, welches von 2 Punkten aufgespannt wird.
	 *
	 * @param a
	 *            Eine Ecke des neuen Rechtecks
	 * @param b
	 *            Die gegenÃ¼berliegende Eckes des neuen Rechtecks
	 */
	Rechteck(Punkt a, Punkt b) {
		// Wir klonen den Punkt a. (Klonen=VollstÃ¤ndig kopieren)
		int ax = a.getX();
		int ay = a.getY();
		this.middle = new Punkt(ax, ay);
		// Und verschieben ihn um die HÃ¤lfte des jeweiligen Achsen-Abstandes
		int dx = (ax - b.getX()) / 2;
		int dy = (ay - b.getY()) / 2;
		this.middle.move(-dx, -dy);
		// Der Betrag der Verschiebung liefert uns gleich die halbe Breite und
		// HÃ¶he
		this.halfwidth = Math.abs(dx);
		this.halfheight = Math.abs(dy);
	}

	/**
	 * Alternativer Konstruktor
	 * 
         * @param r Ein Rechteck, welches geklont wird, d.h. es besteht keine Verbindung zwischen neuem und altem Rechteck Objekt.
         *
	 */
	Rechteck(Rechteck r) {
		// Achtung Falle: "this.middle = r.middle" ist falsch,
		// da Verschiebung des einen Rechtecks plÃ¶tzlich auch das andere
		// Verschieben wÃ¼rde;
		// es muss ein neuer Punkt erzeugt werden! Es sei an Aufgabe 6-2
		// erinnert!
		this.middle = new Punkt(r.middle);
		this.halfheight = r.halfheight;
		this.halfwidth = r.halfwidth;
	}

	/**
	 * 
	 * @return Liefert die X-Koordinate des Mittelpunktes
	 */
	public int getX() {
		return this.middle.getX();
	}

	/**
	 * 
	 * @return Liefert die Y-Koordinate des Mittelpunktes
	 */
	public int getY() {
		return this.middle.getY();
	}

	/**
	 * 
	 * @return Liefert die Breite des Rechtecks
	 */
	public int getWidth() {
		return (2 * this.halfwidth);
	}

	/**
	 * 
	 * @return Liefert die HÃ¶he des Rechtecks
	 */
	public int getHeight() {
		return (2 * this.halfheight);
	}

	/**
	 * 
	 * @param dx
	 *            Verschiebt das Rechteck um dx in der X-Koordinate
	 * 
	 * @param dy
	 *            Verschiebt den Rechteck um dy in der Y-Koordinate
	 */
	public void move(int dx, int dy) {
		this.middle.move(dx, dy);
	}

	/**
	 * Verschiebt das Rechteck um seine eigene Breite nach rechts
	 */
	public void moveWidth() {
		this.middle.move(2 * this.halfwidth, 0);
	}

	/**
	 * 
	 * @param p
	 *            Ein Punkt, zu dem die Distanz vom Mittelpunkt aus berechnet
	 *            werden soll
	 * 
	 * @return Berechnete Distanz des Mittelpunktes zum gegebenen Punkt
	 */
	public double distance(Punkt p) {
		return this.middle.distance(p);
	}

	/**
	 * Halbiert beide Kanten des Rechtecks; der Mittelpunkt bleibt unver\"andert
	 */
	public void half() {
		this.halfheight /= 2;
		this.halfwidth /= 2;
	}

	
	/**
	 * 
	 * @return Liefert linke obere Ecke (kleinste Kooridnaten) des Rechtecks als neuen Punkt
	 */
	public Punkt getUpperLeft() {
		Punkt p = new Punkt(this.middle);
		p.move(-this.halfwidth, -this.halfheight);
		return p;
	}

	
	/**
	 * 
	 * @return Liefert rechte untere Ecke (groesste Kooridnaten) des Rechtecks als neuen Punkt
	 */
	public Punkt getLowerRight() {
		Punkt p = new Punkt(this.middle);
		p.move(this.halfwidth, this.halfheight);
		return p;
	}

	/**
	 * Verschiebt das Rechteck bÃ¼ndig zur linken obere Ecke (kleinste Koordinaten) eines gegebenen
	 * Rechtecks
	 * 
	 * @param l
	 *            Rechteck mit dessen linker oberer Ecke (kleinste Koordinaten) bÃ¼ndig geschoben
	 *            werden soll
	 */
	public void alignUpperLeft(Rechteck ll) {
		Punkt p = ll.getUpperLeft();
		p.move(this.halfwidth, this.halfheight);
		this.middle = p;
	}

	/**
	 * Skaliert Breite und HÃ¶he des Rechtecks, ohne PrÃ¼fung auf SonderfÃ¤lle wie negative Faktoren
	 * @param fx  Faktor zur Skalierung der Breite
	 * @param fy  Faktor zur Skalierung der HÃ¶he
	 */
	public void scale(int fx, int fy) {
		halfwidth *= fx;
		halfheight *= fy;
	}
	
	/**
	 * VergrÃ¶ÃŸert das Rechteck zum kleinstmÃ¶glichen Quadrat, 
	 * in welches das Rechteck noch hineinpasst,
	 * ohne den Mittelpunkt des Rechtecks zu verschieben.      
	 */
	public void square() {
		if (this.halfwidth < this.halfheight) {
			this.halfwidth = this.halfheight;
		} else {
			this.halfheight = this.halfwidth;
		}
	}
}
```


----------

