2017-01-01 79 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