2016-08-08 12 views
1

私は飛行機を形成するポイントのリストを持っています。私は連続した点の間にエッジを作成し、別のリストに追加したい。ここで最後の反復ステップが最初のオブジェクトに戻るようにリストを反復処理する方法は?

は、私が現在持っているコードは次のとおりです。

// Get points forming the plate 
ArrayList points = part.points; 

// Number of points forming the plate 
int pointCount = points.Count; 

// Create edges 
List<LineSegment> edges = new List<LineSegment>(); 
for (int i = 0; i < pointCount - 1; i++) 
{ 
    // Get start and end points 
    Point start = points[i]; 
    Point end = points[i+1]; 

    // Create edge 
    LineSegment edge = new LineSegment(start, end); 

    // Add edge to the list 
    edges.Add(edge); 
} 

それが最後とリストの最初の点の間の最後のエッジを作成していないので、それは非常に動作しません。それを修正する方法は何でしょうか?私はそれがこのようなif文で動作させることができます:

for (int i = 0; i < pointCount; i++) 
{ 
    // Get start and end points 
    Point start = points[i] as Point; 
    Point end; 
    if (i == pointCount-1) end = points[0] as Point; 
    else end = points[i+1] as Point; 

    // Rest of the code here 
} 

しかし、私はそれを行うにはよりエレガントな方法があることを確認しています。 Pythonでは、最初の辺が実際に最後の点を最初の点に接続するように-1からループを開始しますが、これはC#では不可能です。

EDIT:ポイントリストはAPIによってArrayListとして与えられます。

+2

質問以外は、 'ArrayList'の代わりに' List 'を使ってください。これにより、型付きのコレクションが得られます。 – Habib

+0

ループをそのままの状態に保ち、ループの外側で最後のステップを行うのはなぜですか?点[0]と点[points.Length-1]の間をリンクする、常に同じコマンドである必要があります。 –

+0

downvoteについては分かりませんが、これはokの質問のようです。 – Habib

答えて

7

「エレガント」ソリューションは、moduloを使用している:

for (int i = 0; i < pointCount; i++) 
{ 
    … 
    // for i+1 == pointCount this will yield points[0] 
    Point end = points[(i+1) % pointCount] as Point; 
    … 
} 

しかし、私はあなたが使用if文は、より読みやすいと考えています。

注:ArrayListの代わりにList<T>を使用してください。

0

モジュロ演算子(C#では '%')を使用します。

for (int i = 0; i < pointCount; i++) 
{ 
    // Get start and end points 
    Point start = points[i] as Point; 
    Point end = points[(i + 1) % pointCount]; 

    // Rest of the code here 
} 
0

すべてのインデックスと明示的なループをすべて削除し、解決方法ではなく問題自体を説明します。

var offsetPoints = points.Skip(1).Concat(new[]{points.First()}); 

List<LineSegment> edges = 
    points.Zip(offsetPoints, (p1, p2) => new LineSegment(p1, p2)).ToList(); 

私はちょうど開始時に最初の要素をスキップし、オフセットリストと元のリストは同じ長さであるので、最後にそれを追加するオフセットリストを作成します。例示のため

、私はいくつかの配列で開始されるだろう:

{P1、P2、P3、P4、P5}

および配列を製造:

{p2、p3、p4、p5、p1}

次に、それらをまとめて、各シーケンスの同じ位置に現れる点の線分。

は、任意の関数を使用して両方の要素から新しい配列を作成し、上記の例を続ける:

{F(P1、P2)、F(P2、P3)、F(P3、P4 )、f(p4、p5)、f(p5、p1)}

ここで、fは私の提供するジップ機能です。

このアプローチでは、コードがはるかに少なく、インデックス作成のバグにつながる可能性は非常に低くなります。

関連する問題