2 çokgenim var. Her iki poligonun tepe koordinatlarını biliyorum. Birinin diğerinin içinde olup olmadığını kontrol etmenin en iyi yolu nedir? Örneğin, algoritma aşağıdaki siyah trapezoid'i içerdiği şekilde tanımalıdır :
2 çokgenim var. Her iki poligonun tepe koordinatlarını biliyorum. Birinin diğerinin içinde olup olmadığını kontrol etmenin en iyi yolu nedir? Örneğin, algoritma aşağıdaki siyah trapezoid'i içerdiği şekilde tanımalıdır :
Yanıtlar:
" Poligon içindeki nokta " için bir test gerçekleştiren bir yöntem için tonlarca kaynak parçacığı vardır . İlke Ürdün'ün çokgenler için eğri teoreminden ( http://www-cgrl.cs.mcgill.ca/~godfried/teaching/cg-projects/97/Octavian/compgeom.html ) gelir.
Naif yol şu olurdu: bu yönteme sahip olmak, şöyle deyin 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;
Teorik olarak, çokgenleriniz için herhangi bir senaryoyu kaçırmamalı, ancak bu en uygun çözüm değildir.
"Edge" vaka yorumları
PointInsidePolygon(..)
nokta çokgenin sınırındaysa doğru dönmelidir (ya bir kenarda ya da bir tepe noktasıdır)
EdgesIntersect(..)
innerEdge
öğesinin bir alt kümesi (geometrik olarak) ise false değerini döndürmelidir outerEdge
. Bu durumda, kenarlar açıkça kesişir, ancak algoritmanın amacı için, kesişimin isInside
değişkenin arkasındaki anlambilimi kırmadığını belirtmemiz gerekir.
Genel Hatırlatmalar :
kenarlarda kenar kesişme kontrolleri olmadan, yorumlarda belirtildiği gibi, yaklaşım bazı içbükey çokgenler için yanlış pozitifler döndürebilir (örneğin V şekilli bir dörtlü ve bir dikdörtgen - dikdörtgen, V şeklinin içindeki tüm köşelerine sahip olabilir, ancak kesişebilir , bu nedenle en azından bazı alanların dışında).
iç poligonun köşelerinden en az birinin dış kenarın içinde olup olmadığını kontrol ettikten sonra ve kesişen kenarlar yoksa, aranan koşulun sağlandığı anlamına gelir.
Her kırmızı çizgi ile bir çizgi kesişimi yapmayı deneyin. Sözde kodda:
// 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
}
Ancak, gördüğünüz gibi, kontrol etmek için daha fazla çokgen ekledikçe bu çözüm yavaşlar. Farklı bir çözüm şunlar olabilir:
Bu çözüm çok hızlıdır, ancak sizin uygulamanıza (ve kontrolünüzün sonucuyla ne yapmak istediğinize) bağlıdır.