2つのポリゴンがあります。両方のポリゴンの頂点座標を知っています。一方が他方の中に完全にあるかどうかを確認する最良の方法は何ですか?たとえば、アルゴリズムは以下の黒い台形のみが含まれていると認識します。
2つのポリゴンがあります。両方のポリゴンの頂点座標を知っています。一方が他方の中に完全にあるかどうかを確認する最良の方法は何ですか?たとえば、アルゴリズムは以下の黒い台形のみが含まれていると認識します。
回答:
「ポリゴン内のポイント」のテストを実行するメソッドには、多数のソーススニペットがあります。原理は、ポリゴンに関するジョーダンの曲線定理(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つの頂点が外側の頂点の内側にあることを確認し、交差するエッジがない場合は、シークアフター条件が満たされていることを意味します。
それぞれの赤い線と線の交点を作ってみてください。疑似コード:
// 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
}
ただし、ご覧のように、チェックするポリゴンをさらに追加すると、このソリューションは遅くなります。別の解決策は次のとおりです。
このソリューションは非常に高速ですが、どのソリューションが最適であるかは、実装(およびチェックの結果で何をしたいか)によって異なります。