# Rechtecke rekursiv zeichnen



## kantolyo123 (16. Dez 2015)

Ich möchte ein Rechteck zeichnen und dieses dann immer weiter halbieren an der längeren Seite, so dass immer weitere kleinere Rechtecke innerhalb des ersten entstehen. Bin mir aber noch nicht ganz sicher wie ich das machen kann und möchte euch daher um Hilfe bitten. Bisher bin ich soweit:

```
public class Rechteck {
  public static void zeichneRechteck(double a,double b) {
   a=0.9;
   b=0.7;
   StdDraw.line(0.2,0.2,0.2,a);
   StdDraw.line(0.2,a,b,a);
   StdDraw.line(b,a,b,0.2);
   StdDraw.line(b,0.2,0.2,0.2);
}
  public static void zeichne(double n, double a, double b) {
   if(n==0) return;
   zeichneRechteck(a,b);

   zeichne(n-1,a,b);
}
  public static void main(String[]args) {
   int n=Integer.parseInt(args[0]);
   double a=0.9;
   double b=0.45;
   zeichne(n,a,b);
}
}
```

Bisher entsteht nur das erste Rechteck und kein weiteres innerhalb des ersten.


----------



## Joose (16. Dez 2015)

Logisch in deiner Methode "zeichneRechteck" hast du die Parameter a und b, für beide setzt du immer die gleichen Werte. Daher wird jedes Reckteck genau über dem vorherigen gezeichnet. Für dich schaut es nach nur einen aus. -> a und b nicht auf einen fixen Wert setzen.

Was bei dir fehlt ist das halbieren einer Seite (egal welche der beiden, aber nicht beide)


----------



## kantolyo123 (16. Dez 2015)

Erst einmal vielen Dank für deine Antwort! Das heißt also, ich brauche a und b nicht weiter definieren, aber das erste Rechteck muss ich schon mit konkreten Zahlen zeichnen, oder? Wo genau muss ich die Seite halbieren?


----------



## Joose (16. Dez 2015)

kantolyo123 hat gesagt.:


> ...... Das heißt also, ich brauche a und b nicht weiter definieren, aber das erste Rechteck muss ich schon mit konkreten Zahlen zeichnen, oder?


Natürlich brauchst du Anfangswerte für a und b. Diese legst du auch in der main Methode fest.
Danach musst du aber nur noch die Werte halbieren. Praktisch wäre es hier a und b abwechselnd zu halbieren (Tipp: abhängig von n).



kantolyo123 hat gesagt.:


> Wo genau muss ich die Seite halbieren?


Dort wo es Sinn ergibt 
Überlege was dein Program aktuell macht und wo es Sinn macht eine der Längen zu halbieren.


----------



## kantolyo123 (16. Dez 2015)

Okay, werde das mal versuchen und melde mich später noch einmal. Danke für deine Hilfe!


----------



## kantolyo123 (16. Dez 2015)

Jetzt brauche ich doch noch einmal deine Hilfe. Habe es jetzt hinbekommen, dass das Rechteck an der langen Seite geteilt wird, aber leider nicht genau durch die Hälfte, sodass zwei gleich große Rechtecke entstehen. Leider verstehe ich (noch) nicht, warum das so ist. 
Ich möchte im nächsten Schritt dann auch das Rechteck abwechselnd durch a und b teilen, so dass unmittelbar nach der Teilung zwei gleich große Rechtecke entstehen. Du hast gesagt, das ist von n abhängig. Heißt das, dass ich eine if Schleife machen muss mit einmal geraden Zahlen und einmal ungeraden Zahlen? Aber wie genau kann ich das deklarieren? Oder bin ich jetzt komplett auf dem Holzweg?


----------



## Joose (16. Dez 2015)

kantolyo123 hat gesagt.:


> Habe es jetzt hinbekommen, dass das Rechteck an der langen Seite geteilt wird, aber leider nicht genau durch die Hälfte, sodass zwei gleich große Rechtecke entstehen. Leider verstehe ich (noch) nicht, warum das so ist.



Was heißt nicht genau durch die Hälfte? Hast du dir auf der Konsole die Werte ausgeben lassen welche der Reihe nach berechnet werden. Wie schaut dein Code aus? Wie halbierst du?
double und float sind ungenau und können nicht immer "genau" halbiert werden, aber das sollte nicht so groß ins gewicht fallen.



kantolyo123 hat gesagt.:


> Ich möchte im nächsten Schritt dann auch das Rechteck abwechselnd durch a und b teilen, so dass unmittelbar nach der Teilung zwei gleich große Rechtecke entstehen. Du hast gesagt, das ist von n abhängig. Heißt das, dass ich eine if Schleife machen muss mit einmal geraden Zahlen und einmal ungeraden Zahlen? Aber wie genau kann ich das deklarieren?



Bezüglich der "if-Schleife" => http://if-schleife.de/

Genau abhängig von davon ob n gerade oder ungerade ist kannst du eben a oder b halbieren.
Dazu diesen Link: https://www.google.at/search?q=java...-8&oe=utf-8&gws_rd=cr&ei=tDdxVq2wLofXUcHUr-AG


----------



## kantolyo123 (16. Dez 2015)

Sorry, habe vergessen den Code anzuhängen.

```
public class Rechteck {
  public static void zeichneRechteck(double a,double b) {
   StdDraw.line(0.2,0.2,0.2,a);
   StdDraw.line(0.2,a,b,a);
   StdDraw.line(b,a,b,0.2);
   StdDraw.line(b,0.2,0.2,0.2);
}
  public static void zeichne(double n, double a, double b) {
   if(n==0) return;
   zeichneRechteck(a,b);

   zeichne((n-1),a/2,b);
}
  public static void main(String[]args) {
   int n=Integer.parseInt(args[0]);
   double a=0.9;
   double b=0.7;
   zeichne(n,a,b);
}
}
```


----------



## Joose (16. Dez 2015)

Naja du zeichnest eigentlich kein Rechteck sondern 4 Linien welche ein Reckteck ergeben sollen.
Da ich die Klasse "StdDraw" nicht kenne und weiß was sie (und ihre Methoden) genau machen bzw. welche Parameter sie haben wollen ist es schwer zu sagen warum er dir nicht genau halbiert.

PS: Ein Screenshot davon wäre praktisch, dann kann man sich es auch in etwa vorstellen


----------



## kantolyo123 (16. Dez 2015)

Habe StdDraw von dieser Seite. 
http://introcs.cs.princeton.edu/java/stdlib/StdDraw.java


----------



## kantolyo123 (16. Dez 2015)

Hier noch eine Zeichnung meines bisherigen Rechtecks


----------



## Joose (16. Dez 2015)

Schau dir doch mal genau an welche Parameter die Methode "line" erwartet.
Dann schau dir deinen Code an:


```
public static void zeichneRechteck(double a,double b) {
   StdDraw.line(0.2,0.2,0.2,a); // 1.Linie
   StdDraw.line(0.2,a,b,a); // 2.Linie
   StdDraw.line(b,a,b,0.2); // 3.Linie
   StdDraw.line(b,0.2,0.2,0.2); 4.Linie
}
```

Du zeichnest deine 4 Linien schon mit einem Grundabstand zum Rand ... diesen Grundabstand musst du bei a und b miteinbeziehen!


----------



## kantolyo123 (16. Dez 2015)

Danke, das klappt jetzt. Das Rechteck wird genau durch die Hälfte geteilt. Habe jetzt am Rand angefangen. Jetzt möchte ich aber das das Rechteck bei der nächsten Teilung wieder durch die längere Seite geteilt wird und so ein kleineres Rechteck entsteht. 
Die if Abfrage habe ich folgendermaßen gemacht:

```
if((b%2)==0)
   zeichne((n-1),a,b/2);
   else
   zeichne((n-1),a/2,b);
```
Das Bild sieht aber so aus: Ich möchte aber, dass die untere der beiden inneren Linien senkrecht verläuft und so das Rechteck noch einmal teilt.


----------



## Joose (16. Dez 2015)

Schau dir deine if-Bedingung genau an  vielleicht fällt dir der Fehler auch auf


----------



## kantolyo123 (16. Dez 2015)

Ich fürchte, da muss ich passen. Ich habe absolut keine Ahnung, wo der Fehler ist und keine Idee was ich an der if Bedingung ändern muss.


----------



## Joose (16. Dez 2015)

Ich zitiere mich selber:


Joose hat gesagt.:


> Genau abhängig von davon ob *n* gerade oder ungerade ist kannst du eben a oder b halbieren.



Hier dein Code

```
if((b % 2) == 0)
```


----------



## kantolyo123 (16. Dez 2015)

Das habe ich völlig übersehen. Jetzt habe ich aber noch eine Frage: wenn ich eine gerade Zahl n eingebe, wird zuerst die kürzere Seite geteilt und es entstehen in die Länge gezogene Rechtecke. Warum ist das so? Hatte erwartet, dass die Rechtecke von der Form her gleich aussehen. Im Foto die Eingabe n=4. Und wie kann ich es ändern, dass auch bei der Eingabe einer geraden Zahl immer die längere Seite halbiert wird? Vielleicht mit einer weiteren if Bedingung?


----------



## Joose (16. Dez 2015)

Du könntest auch unabhängig von n entscheiden welche Seite du kürzen willst.
Einfach schauen welche der beiden Seiten länger ist und eben die längere kürzen/halbieren. Dann sollte es keine lang gezogene Recktecke mehr vorkommen.


----------



## kantolyo123 (16. Dez 2015)

Und wie gestalte ich das unabhängig von n? Wie kann ich abfragen, welche Seite länger ist? Vielleicht mit if(a>b)%2==0? Aber da bekomme ich einen Fehler vom Compiler.


----------



## Joose (16. Dez 2015)

kantolyo123 hat gesagt.:


> Und wie gestalte ich das unabhängig von n? Wie kann ich abfragen, welche Seite länger ist?



Bitte lies dir meinen letzten Beitrag aufmerksam durch, dort steht eigentlich genau beschrieben wie es funktioniert 



kantolyo123 hat gesagt.:


> Vielleicht mit if(a>b)%2==0? Aber da bekomme ich einen Fehler vom Compiler.



Logisch weil es syntaxisch völlig falsch ist. Außerdem willst du ein boolean (a>b) mit %2 berechnen. Das %2 == 0 war nur fürs "n" gedacht da sich dies bei jedem Durchlauf der Methode um 1 verringert hat.


----------



## kantolyo123 (16. Dez 2015)

Musste zwischenzeitlich noch etwas anderes erledigen, deswegen hat es diesmal etwas länger gedauert bis zu meiner Antwort. Habe jetzt die Lösung, indem ich das mit einer if Bedingung gemacht habe, was du mir gesagt hast. Vielen Dank für deine Geduld und die super Hilfe!!!


----------

