Tôi có 2 đa giác. Tôi biết tọa độ đỉnh của cả hai đa giác. Cách tốt nhất để kiểm tra xem cái này có hoàn toàn bên trong cái kia không? Ví dụ, thuật toán chỉ nên nhận ra hình thang màu đen bên dưới như được chứa:
Tôi có 2 đa giác. Tôi biết tọa độ đỉnh của cả hai đa giác. Cách tốt nhất để kiểm tra xem cái này có hoàn toàn bên trong cái kia không? Ví dụ, thuật toán chỉ nên nhận ra hình thang màu đen bên dưới như được chứa:
Câu trả lời:
Có hàng tấn đoạn mã nguồn cho một phương thức thực hiện kiểm tra " điểm bên trong đa giác ". Nguyên tắc này xuất phát từ định lý đường cong của Jordan cho đa giác ( http://www-cgrl.cs.mcgill.ca/~godfried/teaching/cg-projects/97/Octavian/compgeom.html ).
Cách ngây thơ sẽ là: có phương pháp đó, gọi nó là 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;
Về mặt lý thuyết, nó không nên bỏ lỡ bất kỳ kịch bản nào cho đa giác của bạn, nhưng đó không phải là giải pháp tối ưu.
Nhận xét trường hợp "Cạnh"
PointInsidePolygon(..)
phải trả về true nếu điểm nằm trên đường viền của đa giác (nằm trên một cạnh hoặc là một đỉnh)
EdgesIntersect(..)
phải trả về false nếu innerEdge
là tập hợp con (thông minh về mặt hình học) của outerEdge
. Trong trường hợp này, các cạnh rõ ràng giao nhau, nhưng với mục đích của thuật toán, chúng ta cần chỉ ra rằng giao điểm không phá vỡ ngữ nghĩa đằng sau isInside
biến
Đại tướng quân :
không có kiểm tra giao điểm cạnh và cạnh, như đã nêu trong các nhận xét, cách tiếp cận có thể trả về giá trị dương cho một số đa giác lõm (ví dụ hình tứ giác hình chữ V và hình chữ nhật - hình chữ nhật có thể có tất cả các đỉnh của nó bên trong hình chữ V, nhưng giao nhau , do đó có ít nhất một số khu vực bên ngoài).
sau khi kiểm tra ít nhất một trong các đỉnh của đa giác bên trong nằm bên trong bên ngoài và nếu không có các cạnh giao nhau, điều đó có nghĩa là điều kiện tìm kiếm được thỏa mãn.
Hãy thử làm một giao điểm đường với mỗi đường màu đỏ. Trong mã giả:
// 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
}
Tuy nhiên, như bạn có thể thấy, giải pháp này sẽ chậm hơn khi bạn thêm nhiều đa giác để kiểm tra. Một giải pháp khác có thể là:
Giải pháp này rất nhanh, nhưng nó phụ thuộc vào việc triển khai của bạn (và những gì bạn muốn làm với kết quả kiểm tra của bạn) giải pháp nào phù hợp nhất với bạn.