问题
I'm learning about constraint programming and recursive programming in
Prolog. I have to programm a koch-curve of Level N which should start at (Sx,Sy)
and end at (Ex,Ey)
.The line-segments, which are being calculated, will be stored in Ls.
When I try to execute generatelines(1,(60,0),(-60,0),Ls)
, I get the right 4
coordinates of the koch-curve of level 1:
[[ (60, 0), (20, 0)],
[ (20, 0), (0.0, -34.64)],
[ (0.0, -34.64), (-20, 0)],
[ (-20, 0), (-60, 0)]]
When I try to execute generatelines(2,(60,0),(-60,0),Ls)
, then I get
all the coordinates between the next start (60,0)
and end point (20,0)
.
But I even need all coordinates between following start and endpoints:
(20, 0), (0.0, -34.64),
(0.0, -34.64), (-20, 0),
(-20, 0), (-60, 0)
too.
My problem is, I don't know how to implement it, to get the coordinates
of a higher level.
Actually I think the following should happen:
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).
Maybe there is somebody here to help me solving this problem.
thanks
This is the code I have until now:
- 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:
You are trying to do too much at once, in one predicate. In many other programming languages it is easy to get carried away and put too much into one function or method; that is a style issue, but it can work. In Prolog, many things simply cannot be expressed without auxiliary predicates, essentially because we have no loops like other languages.
The key here is to decompose your program into several distinct predicates each with its own responsibilities, something like this:
segments(S, E, Ls)
for computing the listLs
of the four "first-level" line segments between start and end pointsS
andE
next_level_segments(Segments, RefinedSegments)
which takes a list of line segmentsSegments
, each of the form[P, Q]
, and generates the "next-level" list of segments between each such pair of end pointsP
andQ
iterate_level(N, InitialSegments, FinalSegments)
which iterates thenext_level_segments
operationN
times
Your final predicate is then simply:
generatelines(N, S, E, Segments) :-
segments(S, E, InitialSegments),
iterate_level(N, InitialSegments, Segments).
Of course you have to define these auxiliary predicates, but that is your homework.
Note also that you are not actually using the clpfd
library.
来源:https://stackoverflow.com/questions/41419143/prolog-calculating-coordinates-of-koch-curve