2013-10-04 87 views
5

因此,我完成了一個程序,遞歸繪製線,其中需要一個參數「n」來定義遞歸的深度。我有兩個功能,一個繪製相對較左的線,另一個繪製相對正確的線。我測試了它,它似乎適用於前4個級別,但隨後線條變得太小而無法準確表示,或者代碼有問題,因爲線條之間的間隔似乎變得隨意。希望有人能測試我的代碼,看看他們是否能找到問題所在。檢查程序調試

下圖是深度的10

編輯:固定部分代碼,仍然需要幫助,雖然

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); 

} 
} 

回答

4

我認爲繪圖看起來是因爲不正確的所有漂亮的雙值都是用離散像素近似,導致線段之間不需要的重疊(參見底部的編輯)。然而,對你的代碼有一些評論:

1)你不需要drawLeftLinedrawRightLine方法,因爲它們目前正在繪製完全相同的東西。由於在每個步驟中您都要撥打cantor兩次(刪除的內部三分之一的每一面都有一次),因此您必須爲每個必須繪製的線段致電cantor。因此,我會將所有繪圖直接放入cantor方法中。

2)由於y0y1都是相同的,所以我會將它們減少到只有一個y變量。

3)我想簡化的數學計算新x0x1值下降到

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

4),而不是由0.1每次遞減y值,你應該有一個確定的全局變量這應該減少的金額(否則如果你嘗試n > 10的東西會打破)。該值可以設置爲1.0/n

5)每次繪畫時不需要設置筆的顏色。您可以在主要方法中只設置一次。

6)StdDraw已在您正在繪製的圖片周圍設置邊框,因此不需要從0.9開始您的座標 - 您可以使用1代替。

以下這些建議的代碼是這樣的:

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); 
} 

編輯:與StdDraw畫布大小,畫布縮放設置,以及線段的端點舍入模式下播放身邊,你可以得到一個稍微好一點的畫面(在下面的代碼生成一個圖片,看起來大多是正確下降到8級)

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); 
} 

要顯示都記錄下來,以絕對正確性第十級則需要3^9個像素(19K像素)的寬度。對於9級,即3^8 = 6K。對於8級即3^7 = 2k,這就是爲什麼它看起來幾乎正確的1.9K像素寬度和整數舍入。

+0

我實際上不允許混淆這個項目的畫布大小,但我會嘗試在幾分鐘內實現這個。它看起來很棒,聽到這可能是一個圖形錯誤也很棒。你是男人!謝謝! – user2782981