2012-11-26 25 views
3

使用處理和遞歸,我想畫一個形狀類似於此: http://i.imgur.com/OPf5D.png試圖繪製一個特定形狀遞歸,嘗試一切可能的方式,我知道如何

但我覺得我要失去我的腦海裏想盡一切辦法畫出形狀。這是最接近我得到了:http://i.imgur.com/vCHJG.png

加上我的代碼,任何幫助,將不勝感激。感謝:

void setup(){ 
    size(600,600); 
} 

void draw(){ 
    background(255); 
    draws(300, 300, 50, 5); 
} 

void draws(int x, int y, int x2, int num){ 
    stroke(0); 
    strokeWeight(2); 
    line (x, y, (x+x2), y); //right 
    line(x, y, x, y-50); //right up 
    line (x-x2, y, x-(x2*2), y); // left 
    line(x-x2, y, x-x2, y-50); //left up 
    line (x, y-50, x-x2, y-50); //top 

    if(num>0){ 
    draws(x-x2, y-x2, x2/2, num-1); 
    } 
} 
+0

爲什麼你在每個地方都使用魔術數字'50'?我想你可以用'x_start','x_end','y_start'和'y_end'來完成這個工作,其中缺口的高度和寬度是'(x_end-x_start)/ 3'。你還必須考慮如何繪製你想用缺口替換的扁平位。 – jozzas

+0

你在用什麼語言? – John

回答

0

我明白了!謝謝您的幫助。

這裏是它的肉,其他的一切都很好:

線(X,Y,X,Y-X2); // right

line(x-x2,y,x-x2,y-x2); //左

如果(NUM> 0){

draws(x-(x2/3), y-x2, x2/3, num-1); // Central one 

draws(x+(x2/1.5), y, x2/3, num-1); // right one 

draws(x-(x2*1.33), y, x2/3, num-1); // left one 

}

如果(NUM == 0){//如果沒有更多的實例中,繪製表示平線

line (x, y, (x+x2), y); //right 

line (x-x2, y, x-(x2*2), y); // left 

line (x, y-x2, x-x2, y-x2); //top 

}

0

(也許這應該是一個評論 - 因爲它不是一個完整的答案 - 但我似乎無法讓它)

也就是說.......

  • 在每個步驟中,您除以2而不是3。
  • 您需要每次繪製3次第二層次'繪製'
  • 您在這裏有'y'座標 - 但x座標錯誤。 在猜測....層次結構應該是這樣的....

`

if(num>0){ 

    draws(x, y-x2, x2/3, num-1); // Central one  
    draws(x-x2, y, x2/3, num-1); // Left One 
    draws(x, y, x2/3/2, num-1); // right one 
} 

`

東西,使得它稍微困難的是,你的座標從一開始右邊的左邊......可能更容易從最左邊或最右邊開始。

0

該邏輯類似於生成Koch分形。這是這樣的:

  1. 畫一條水平直線。
  2. 將該行分成3段。
  3. 將中段向上移動一個段的大小。
  4. 對每個分段重複。

所以,我們的職能應主要試着畫出這條線:

  _________ 
      |   | 
      |   | 
      |   | 
_________|   |_________ 

凡過程重複依次對每個水平線。

我可以想到的一個簡單方法就是直接開始。然後在每次迭代中擦除線的中間並進行升檔(可以在黑線的頂部繪製白線)。

因此,僞代碼將是這樣的:

// Pseudocode: 

fractal (x_start,x_end, y) { 
    // first simply draw a straight line: 
    line(x_start,y,x_end,y); 

    // divide the line into 3 and push the middle up 
    length = x_end-x_start; 
    segment_length = length/3; 
    x2 = x_start+segment_length; 
    x3 = x_start+segment_length*2; 
    y2 = y-segment_length; 
    erase_line(x2,y,x3,y); 
    line(x2,y,x2,y2); // up 
    line(x2,y2,x3,y2); // accross 
    line(x3,y2,x3,y); // down 

    // now repeat for each segment 
    fractal(x_start,y,x2,y); 
    fractal(x2,y2,x3,y2); 
    fractal(x3,y,x_end,y); 
} 

所以這是基本的工作職能。請注意,它不會停止遞歸,因此上述函數將無限地(或直到內存不足)繼續運行。所以首先要做的是增加一個遞歸限制:

// Pseudocode: 

fractal (x_start,x_end, y, limit) { 
    // 
    // same content as above except the last 3 lines 
    // 

    limit --; 
    if (limit) { 
     fractal(x_start,y,x2,y,limit); 
     fractal(x2,y2,x3,y2,limit); 
     fractal(x3,y,x_end,y,limit); 
    } 
} 

這應該是一個很好的起點。

您還可以進行其他優化。例如,你實際上並不需要在開始時繪製直線,因爲每次迭代都會基本再次繪製直線。您只需要在遞歸限制下繪製水平線。這意味着你不需要清除你沒有繪製的線條。但是我將這個實現作爲讀者的練習。

相關問題