2013-10-04 14 views
5

So beendete ich ein Programm, das rekursiv Linien zeichnet, die ein Argument "n" verwendet, um die Tiefe der Rekursion zu definieren. Ich habe 2 Funktionen, eine, die die relativ linke Linie zeichnet und eine andere, die die relativ richtige zeichnet. Ich habe es getestet und es scheint für die ersten 4 Ebenen zu funktionieren, aber dann werden entweder die Zeilen zu klein, um genau darzustellen, oder irgendetwas stimmt nicht mit meinem Code, weil die Unterbrechungen zwischen den Zeilen scheinbar willkürlich werden. Hatte gehofft, jemand könnte meinen Code testen und sehen, ob sie das Problem finden könnten.Überprüfen Sie das Programm debug

Das folgende Bild ist der Tiefe 10.

EDIT: ein Teil des Codes festen, immer noch Hilfe benötigen, obwohl

public class Art 
{ 

//draws the relatively left line 
public static void drawLeftLine(double x0, double y0, double x1, double y1) 
{ 
    //define new x coordinate for line 
    //double x2 = (1/3.0)*(x1 - x0); 

    //color of line 
    StdDraw.setPenColor(StdDraw.BLUE); 


    //draw line by adding new x coord to original 
    StdDraw.line(x0, y0, x1, y1); 

} 
//draw relatively right line 
public static void drawRightLine(double x0, double y0, double x1, double y1) 
{ 
    //define new x coord for line 
    //double x2 = (2/3.0)*(x1 - x0); 

    //color of line 
    StdDraw.setPenColor(StdDraw.BLUE); 


    //draw line by adding new x coord to original 
    StdDraw.line(x0, y0, x1, y1); 

} 

public static void cantor(int n, double x0, double y0, double x1, double y1) 
{ 
    if (n == 0) 
     return; 

    drawLeftLine(x0, y0, x1, y1); 
    drawRightLine(x0, y0, x1, y1); 

    y0 = y0 - 0.1; 
    y1 = y1 - 0.1; 



    cantor(n-1, x0, y0, x0 + ((x1 - x0))/3.0, y1); //left 
    cantor(n-1, (2.0/ 3) * (x1 - x0) + x0, y0, x1, y1); //right 

} 

public static void main(String[] args) 
{ 
    //change n into integer (depth) 
    int n = Integer.parseInt(args[0]); 

    //specify inital values for line 
    double x0 = 0; 
    double y0 = 0.9; 
    double x1 = 0.9; 
    double y1 = 0.9; 



    //recursive function cantor 
    cantor(n, x0, y0, x1, y1); 

} 
} 

Antwort

4

Ich denke, dass die Zeichnung, weil die falsche aussieht die Tatsache, dass alle netten Doppelwerte mit diskreten Pixeln approximiert werden, die eine unerwünschte Überlappung zwischen den Liniensegmenten verursachen (siehe BEARBEITEN unten). Einige Kommentare über Ihren Code jedoch:

1) Sie benötigen die Methoden drawLeftLine und drawRightLine nicht, da sie derzeit genau das Gleiche zeichnen. Da Sie in jedem Schritt zweimal (einmal für jede Seite des gelöschten inneren Drittels) cantor aufrufen, müssen Sie für jedes Liniensegment, das gezeichnet werden muss, einen Aufruf an cantor. Als solche würde ich alle Zeichnungen direkt in die cantor Methode einfügen.

2) Da und y1 beide immer gleich sind, würde ich sie auf nur eine einzige y Variable reduzieren.

3) Ich würde die Mathematik vereinfachen für die Berechnung der neuen x0 und x1 Werte bis

double third = (x1 - x0)/3; 
cantor(n - 1, x0, x0 + third, y); // left 
cantor(n - 1, x1 - third, x1, y); // right 

4) Statt Erniedrigen des y Wert von 0.1 jedes Mal, sollten Sie eine globale Variable, die die entscheidet Betrag, um den dies verringert werden sollte (sonst, wenn Sie versuchen, n > 10 Dinge brechen). Dieser Wert kann einfach auf 1.0/n gesetzt werden.

5) Sie müssen die Farbe des Stifts nicht jedes Mal neu einstellen, wenn Sie malen. Sie können es nur einmal in der Hauptmethode festlegen.

6) StdDraw setzt bereits einen Rahmen um das Bild, das Sie zeichnen, so dass es nicht nötig ist, Ihre Koordinaten von 0.9 zu starten - Sie können stattdessen 1 verwenden.

der folgenden Vorschläge der Code würde wie folgt aussehen:

private static double yIncrement; 

public static void cantor(int n, double x0, double x1, double y) { 
    if (n == 0) 
    return; 

    StdDraw.line(x0, y, x1, y); 

    y = y - yIncrement; 

    double third = (x1 - x0)/3; 
    cantor(n - 1, x0, x0 + third, y); // left 
    cantor(n - 1, x1 - third, x1, y); // right 

} 

public static void main(String[] args) { 
    //change n into integer (depth) 
    int n = Integer.parseInt(args[0]); 

    // specify inital values for line 
    double x0 = 0; 
    double x1 = 1; 
    double y = 1; 

    yIncrement = 1.0/n; 
    StdDraw.setPenColor(Color.BLUE); 

    // recursive function cantor 
    cantor(n, x0, x1, y); 
} 

EDIT: Herumspielen mit der StdDraw Leinwandgröße, Leinwand Skalierungseinstellungen und Liniensegment Endpunkt Rundungsmodus Sie ein etwas besseres Bild bekommen (die Code unten erzeugt ein Bild, das meist korrekt bis zur 8.en Ebene sieht)

private static double yIncrement; 

public static void cantor(int n, double x0, double x1, double y) { 
    if (n == 0) 
    return; 

    x0 = Math.ceil(x0); 
    x1 = Math.floor(x1); 

    StdDraw.line(x0, y, x1, y); 

    y = y - yIncrement; 

    double third = (x1 - x0)/3; 
    cantor(n - 1, x0, x0 + third, y); // left 
    cantor(n - 1, x1 - third, x1, y); // right 

} 

public static void main(String[] args) { 
    // change n into integer (depth) 
    int n = Integer.parseInt(args[0]); 

    int width = 1920; 
    int height = 1080; 

    StdDraw.setCanvasSize(width, height); 

    // specify inital values for line 
    double x0 = 0; 
    double x1 = width; 
    double y = 1; 

    yIncrement = 1.0/n; 
    StdDraw.setPenColor(Color.BLUE); 
    StdDraw.setXscale(0, width); 

    // recursive function cantor 
    cantor(n, x0, x1, y); 
} 

alles anzuzeigen, bis auf die zehnte Ebene mit absoluten Korrektheit Sie eine Breite von 3^9 Pixel benötigen würde (19K Pixel). Für Level 9 ist das 3^8 = 6K. Für Level 8 ist das 3^7 = 2k, weshalb es mit 1.9K Pixel Breite und Integer-Rundung nahezu korrekt aussieht.

+0

Ich bin eigentlich nicht erlaubt, mit der Leinwand Größe für dieses Projekt, aber ich werde versuchen, dies in wenigen Minuten zu implementieren. Es sieht gut aus und es ist auch großartig zu hören, dass es sich wahrscheinlich um einen grafischen Fehler handelt. Du bist der Mann! Vielen Dank! – user2782981

Verwandte Themen