Prolog - 计算科赫曲线的坐标
Prolog - Calculating coordinates of Koch-curve
我正在学习约束编程和递归编程
序言。我必须编写一个 N 级的科赫曲线,它应该从 (Sx,Sy)
开始并在 (Ex,Ey)
结束。正在计算的线段将存储在 Ls.
当我尝试执行 generatelines(1,(60,0),(-60,0),Ls)
时,我得到了正确的 4
1 级科赫曲线的坐标:
[[ (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).
您试图在一个谓词中同时做太多事情。在许多其他编程语言中,很容易被冲昏头脑,在一个函数或方法中投入太多;这是一个风格问题,但它可以工作。在 Prolog 中,如果没有辅助谓词,许多事情根本无法表达,主要是因为我们没有像其他语言那样的循环。
这里的关键是将你的程序分解成几个不同的谓词,每个谓词都有自己的职责,就像这样:
segments(S, E, Ls)
用于计算起点和终点S
和E
之间的四个"first-level"线段的列表Ls
next_level_segments(Segments, RefinedSegments)
获取线段列表 Segments
,每个线段的形式为 [P, Q]
,并在每一对末端之间生成 "next-level" 线段列表点 P
和 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
库。
我正在学习约束编程和递归编程
序言。我必须编写一个 N 级的科赫曲线,它应该从 (Sx,Sy)
开始并在 (Ex,Ey)
结束。正在计算的线段将存储在 Ls.
当我尝试执行 generatelines(1,(60,0),(-60,0),Ls)
时,我得到了正确的 4
1 级科赫曲线的坐标:
[[ (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).
您试图在一个谓词中同时做太多事情。在许多其他编程语言中,很容易被冲昏头脑,在一个函数或方法中投入太多;这是一个风格问题,但它可以工作。在 Prolog 中,如果没有辅助谓词,许多事情根本无法表达,主要是因为我们没有像其他语言那样的循环。
这里的关键是将你的程序分解成几个不同的谓词,每个谓词都有自己的职责,就像这样:
segments(S, E, Ls)
用于计算起点和终点S
和E
之间的四个"first-level"线段的列表next_level_segments(Segments, RefinedSegments)
获取线段列表Segments
,每个线段的形式为[P, Q]
,并在每一对末端之间生成 "next-level" 线段列表点P
和Q
iterate_level(N, InitialSegments, FinalSegments)
迭代next_level_segments
操作N
次
Ls
你的最终谓词就是:
generatelines(N, S, E, Segments) :-
segments(S, E, InitialSegments),
iterate_level(N, InitialSegments, Segments).
当然你必须定义这些辅助谓词,但那是你的功课。
另请注意,您实际上并未使用 clpfd
库。