1つのポリゴンに別のポリゴンが完全に含まれているかどうかを確認するにはどうすればよいですか?


9

2つのポリゴンがあります。両方のポリゴンの頂点座標を知っています。一方が他方の中に完全にあるかどうかを確認する最良の方法は何ですか?たとえば、アルゴリズムは以下の黒い台形のみが含まれていると認識します。

ポリゴンの例


現時点では詳細な答えを出すことはできません(後で行う可能性があります)が、衝突検出の分離軸定理の実装を確認する必要があります。アルゴリズムを少し変更して、必要なものを簡単に確認できます。例:codezealot.org/archives/55
TravisG

1
ポリゴン内部のポリゴンについて理解していることが明確ではありません。小さい方のポリゴンのすべてのポイントが大きい方のポイントにあるが、それぞれのポイントが1本の線上にある場合、それらは相互にあるのでしょうか。i47.tinypic.com/4i0sgg.jpg
speedyGonzales

@speedyGonzales、これは内部で呼ばれています。
user960567 2012年

回答:


5

ポリゴン内のポイント」のテストを実行するメソッドには、多数のソーススニペットがあります。原理は、ポリゴンに関するジョーダンの曲線定理(http://www-cgrl.cs.mcgill.ca/~godfried/teaching/cg-projects/97/Octavian/compgeom.html)に基づいています

素朴な方法は次のとおりです:そのメソッドを持ち、それを呼び出すPointInsidePolygon(Point p, Polygon poly)

  bool isInside = true;
  for each (Point p in innerPoly)
  {
    if (!PointInsidePolygon(p, outerPoly))
    {
      isInside = false; // at least one point of the innerPoly is outside the outerPoly
      break;
    }
  }
  if (!isInside) return false;
  // COMPULSORY EDGE INTERSECTION CHECK
  for each (innerEdge in innerPoly)
    for each (outerEdge in outerPoly)
    {
      if (EdgesIntersect(innerEdge, outerEdge))
      {
        isInside = false;
        break;
      }
    }

  return isInside;

理論的には、ポリゴンのシナリオを見逃してはなりませんが、最適なソリューションではありません。

「エッジ」のケースの注釈

  • PointInsidePolygon(..) ポイントがポリゴンの境界上にある(エッジ上にあるか頂点である)場合、trueを返す必要があります

  • EdgesIntersect(..)innerEdgeがのサブセット(幾何学的に)の場合は、falseを返す必要がありouterEdgeます。この場合、エッジは明らかに交差しますが、アルゴリズムの目的のために、交差がisInside変数の背後にあるセマンティクスを壊していないことを示す必要があります。

一般Remakrs

  • コメントで指摘されているように、エッジとエッジの交差チェックがないと、一部の凹形ポリゴン(V字形の四角形や長方形など)に対して誤検出が返される可能性があります。長方形の頂点はすべてV字形の内側にあるが、交差している場合があります。 、したがって、少なくとも一部の領域が外側にあります)。

  • 内側のポリゴンの少なくとも1つの頂点が外側の頂点の内側にあることを確認し、交差するエッジがない場合は、シークアフター条件が満たされていることを意味します。


1
これは、外側のポリゴンが凹型の場合に誤検知を返します。
sam hocevar

2
面白いことに、teodronとknight666は個別に間違っていますが、組み合わせると正しい答えが得られます。ポリゴンのすべてのポイントが別のポイントの内側にあり、それらのラインが交差しない場合、最初のポリゴンは完全にもう一方の内部にあります。
ハックワース

True、False Positiveを返します。エッジの交差も考慮する必要があります。
teodron

これは正解のようです。2番目のループ状態を確認する必要はないと思います。
user960567 2012年

これは、端点の交差やエッジが重なっている場合には機能しません。
Brandon Kohn 2016年

2

それぞれの赤い線と線の交点を作ってみてください。疑似コード:

// loop over polygons
for (int i = 0; i < m_PolygonCount; i++)
{
    bool contained = false;

    for (int j = 0; j < m_Polygon[i].GetLineCount(); j++)
    {
        for (int k = 0; k < m_PolygonContainer.GetLineCount(); k++)
        {
            // if a line of the container polygon intersects with a line of the polygon
            // we know it's not fully contained
            if (m_PolygonContainer.GetLine(k).Intersects(m_Polygon[i].GetLine(j)))
            {
                contained = false;
                break;
            }
        }

        // it only takes one intersection to invalidate the polygon
        if (!contained) { break; }
    }

    // here contained is true if the polygon is fully inside the container
    // and false if it's not
}

ただし、ご覧のように、チェックするポリゴンをさらに追加すると、このソリューションは遅くなります。別の解決策は次のとおりです。

  • コンテナーポリゴンを白色のピクセルバッファーにレンダリングします。
  • 子ポリゴンを白色の異なるピクセルバッファーにレンダリングします。
  • XORマスクでポリゴンバッファーの上にコンテナーバッファーをマスクします。
  • 白いピクセルの数を数えます。0より大きい場合、子ポリゴンはコンテナに完全には含まれていません。

このソリューションは非常に高速ですが、どのソリューションが最適であるかは、実装(およびチェックの結果で何をしたいか)によって異なります。


1
完全に含まれるポリゴンを見つけるには、ラインの交差だけでは不十分です。
カイロタン

1
質問:ポリゴンが完全に分離している場合、エッジは交差しません。この場合は機能しますか?2番目のグラフィックスベースのアプローチは実際に機能するはずです。
teodron
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.