2017-01-01 69 views
2

我正在學習約束編程和遞歸編程 Prolog。我必須編程一個N級Koch曲線,該曲線應該在(Sx,Sy)開始,結束於(Ex,Ey)。正在計算的線段將存儲在Ls中。
當我嘗試執行generatelines(1,(60,0),(-60,0),Ls),我得到正確的1級的科赫曲線的4個 座標:Prolog - 計算Koch曲線的座標

[[ (60, 0), (20, 0)], 
[ (20, 0), (0.0, -34.64)], 
[ (0.0, -34.64), (-20, 0)], 
[ (-20, 0), (-60, 0)]] 

當我嘗試執行generatelines(2,(60,0),(-60,0),Ls),然後我得到 所有在下次啓動之間的座標(60,0)和終點(20,0)。 但我甚至需要以下起點和終點之間的所有座標:

(20, 0), (0.0, -34.64), 
(0.0, -34.64), (-20, 0), 
(-20, 0), (-60, 0) 

了。

我的問題是,我不知道如何實現它,以獲得更高水平的座標 。
其實我覺得下面應該發生:

generatelines(N1,(60,0),(20,0),Ls1) 
generatelines(N1,(20,0),(0,-34.64),Ls1) 
generatelines(N1,(0,-34.64),(-20,0),Ls1) 
generatelines(N1,(-20,0),(-60,0),Ls1). 

也許有別人來幫我解決這個問題。
感謝

這是我的代碼至今:

- consult(library(clpfd)). 
generatelines(0,_,_,Ls):- !. 
generatelines(N, (Sx,Sy),(Ex,Ey),[Ls|Ls1]):- 
N1 is N-1, 

X2 is Sx+(Ex-Sx)/3, 
Y2 is Sy+(Ey-Sy)/3, 
R1 is sqrt((X2-Sx)*(X2-Sx)+(Y2-Ey)*(Y2-Ey)), 
Phi1 is atan((Y2-Sy)/(X2-Sx)), 
X3 is X2 +R1*cos((Phi1-240)*pi/180), 
Y3 is Y2 +R1*sin((Phi1+240)*pi/180), 
X4 is X2+(X2-Sx), 
Y4 is Y2+(Y2-Sy), 
Ls = [ 
     [(Sx,Sy),(X2,Y2)], 
     [(X2,Y2),(X3,Y3)], 
     [(X3,Y3),(X4,Y4)], 
     [(X4,Y4),(Ex,Ey)] 
    ], 
generatelines(N1,(Sx,Sy),(X2,Y2),Ls1). 

回答

1

你正在嘗試做的太多了一次,在一個謂語。在許多其他編程語言中,很容易被拿走,並將太多功能或方法放在一起;這是一個風格問題,但它可以工作。在Prolog中,許多事情根本無法在沒有輔助謂詞的情況下表達,主要是因爲我們沒有像其他語言一樣的循環。

這裏的關鍵是分解你的程序分爲幾個不同的謂詞每一個都有自己的責任,這樣的事情:

  • segments(S, E, Ls)計算列表中的四個「第一級」行開始之間的段Ls點和結束點SE
  • next_level_segments(Segments, RefinedSegments)這需要線段Segments,各形式[P, Q]的列表,並且生成每一個這樣的對端點P一個之間的段的「下一級」列表d Q
  • iterate_level(N, InitialSegments, FinalSegments)它迭代的next_level_segments操作N

您的最終謂詞是那麼簡單:

generatelines(N, S, E, Segments) :- 
    segments(S, E, InitialSegments), 
    iterate_level(N, InitialSegments, Segments). 

當然,你必須定義這些輔助謂詞,但這是你的功課。

還請注意,您實際上沒有使用clpfd庫。

+0

非常感謝您的回答!嘗試了您的建議,但仍然存在問題:-( – claire