2017-01-09 9 views
0

プロローグでリストを繰り返して、生成された結果を新しいリストに書きたいと思います。 述語でnext_level_segments(List of Start-, Endcoordinates) 私はStart-とEndcoordinatesの各ペアの間の4つの座標の4つのリストを計算し、この4つのリストをLに格納したいと思います。 Iは、例えば[(10,0),(3.3,0)]ためのスタート - 及びEndcoordinatesの 一対の間に4点の次の座標を計算する必要があり述語segments()プロローグのリストを反復する

next_level_segments([ 
         [(10,0),(3.3,0)], 
         [(3.3,0),(0,-5.8)], 
         [(0,-5.8),(-3.3,0)], 
         [(-3.3,0),(-10,0)] 
        ]) 

例えば呼び出したときにこれが意味します。 next_level_segmentsは開始点と終了点のリストを反復する必要があります。セグメントは計算を行い、4つのリストの結果を得て、各4組の座標を結果のリストに格納します。

4つの座標のリストをnext_level_segments()と呼ぶと、計算が完了し、トレースを見ると座標が生成されますが、正しく格納されません。 トレースで見ることができる限り、4つの座標の最後のリストがありません。 誰かが見て、私が間違っていることをいくつかアドバイスしているかもしれません。

はあなたに

segments([(Sx,Sy),(Ex,Ey)],Ls):- 
    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)]].  

next_level_segments([[(Sx,Sy),(Ex,Ey)]|E],[X|RLs]):- 
    segments([(Sx,Sy),(Ex,Ey)],X), 
    next_level_segments(E,RLs). 

next_level_segments([],[]). 

答えて

4

あなたnext_level_segments/2ニーズ(代わりに使用している3の)唯一の2つの節をありがとうございます。最初のものは:

next_level_segments([], []). 

のいずれかでなければなりません。あなたが今のところ持っている最初と3番目の節は、何も役に立たないために行ってください。

再帰的節は現時点では問題ありません。このように修正さ

は、私が取得: segments/2を適用し、言い換えれば

maplist(segments, Input, Output) 

?- next_level_segments(
     [[(10,0),(3.3,0)], 
     [(3.3,0),(0,-5.8)], 
     [(0,-5.8),(-3.3,0)], 
     [(-3.3,0),(-10,0)] 
     ], 
     X). 
X = [[[(10, 0), (7.766666666666667, 0)], [(7.766666666666667, 0), (6.649999999999999, -1.9341234017852458)], [(6.649999999999999, -1.9341234017852458), (5.533333333333333, 0)], [(5.533333333333333, 0), (3.3, 0)]], 
    [[(3.3, 0), (2.2, -1.9333333333333333)], [(2.2, -1.9333333333333333), (0.1262841490828066, -5.451200543142186)], [(0.1262841490828066, -5.451200543142186), (1.1000000000000005, -3.8666666666666667)], [(1.1000000000000005, -3.8666666666666667), (0, -5.8)]], 
    [[(0, -5.8), (-1.0999999999999999, -3.8666666666666663)], [(-1.0999999999999999, -3.8666666666666663), (-3.0456930398351094, -7.310619872034865)], [(-3.0456930398351094, -7.310619872034865), (-2.1999999999999997, -1.9333333333333327)], [(-2.1999999999999997, -1.9333333333333327), (-3.3, 0)]], 
    [[(-3.3, 0), (-5.533333333333333, 0)], [(-5.533333333333333, 0), (-6.65, -1.9341234017852458)], [(-6.65, -1.9341234017852458), (-7.766666666666667, 0)], [(-7.766666666666667, 0), (-10, 0)]] 
    ]. 

このような些細なリスト反復は、単にのように書くことができることを覚えておいてください2つのリストの対応する各要素に割り当てます。彼らはあなたの入力リストであるように、リスト内の2つの最初の引数を置く

segments([(Sx,Sy),(Ex,Ey)], Ls) 

(:あなたは、頭を再度書き込むことによって、例えば、二つの引数の代わりに、3を持っているが、あなたのsegments/3を再定義する必要があります)

小さなコメント:通常、PrologのペアはX-Yと書かれ、(X, Y)ではありません。多くの標準ライブラリ述部は、、ライブラリ(ペア)など、X-Yのような "ペア"を表します。また、ペアにpair(X,Y)coordinates(X,Y)のようなわかりやすい名前を付けることもできます。これは、の2つの要素だけは本当に問題ではないが、このような三つの要素を持つ「タプル」:(X,Y,Z)は実際には、ネストされた用語である:

?- write_canonical((X,Y,Z)). 
','(_,','(_,_)) 
true. 

あなたはX-Y-Zと同じ問題を得る:

?- write_canonical(X-Y-Z). 
-(-(_,_),_) 
true. 

この時点で、わかりやすい名前の用語を再度使用できます(例:triple(X, Y, Z)またはcoordinates(X, Y, Z))。

+0

ボリス!ご回答どうもありがとうございました。私は、あなたが書いたものに従って実装を編集しました。私があなたを正しく理解していれば、括弧を挿入することでセグメント/ 3をセグメント/ 2に変更する必要があります。不要な節を削除し、next_level_segments([]、[]) 'という第3節として挿入しました。私はマッピングの代わりにマッピングを使用することができますが、私はそうする必要はありません - 私はこの権利を理解しましたか?私はそれをやったことがありますが、next_level_segments([()、()、()、()]、[()、()]、[()、()]] )。 "4座標で今私はfalseを取得します。もう一度見てください、私は間違った何かを理解したと思いますか? – claire

+0

私は「第2の」節として意味していました... – claire

+0

@claire編集した質問に表示されているとおり、正確なコードで私にとってはうまくいきます。私の編集を参照してください。 –