Đây là một câu hỏi cũ, nhưng tôi nghĩ tôi cũng sẽ chia sẻ giải pháp của mình. Region.IsEmpty() đòi hỏi một bối cảnh đồ họa và từ sự hiểu biết của tôi chỉ được thiết kế để thực hiện kiểm tra hit chính xác pixel. Đây không phải là lý tưởng cho nhiều tình huống. Một giải pháp tốt hơn là sử dụng thư viện Clipper của Angus Johnson. Theo kinh nghiệm của tôi, đây là một thư viện được kiểm tra nhanh. Bạn có thể cung cấp độ chính xác của riêng bạn và nó xử lý các đa giác cực kỳ phức tạp.
http://www.angusj.com/delphi/clipper.php
Có triển khai C#. Những gì bạn cần làm là thực hiện một thao tác giao cắt giống như phương thức System.Drawing.Region. Sau đó kiểm tra kết quả của hoạt động. Nếu nó trống không có giao lộ. Nếu nó chứa dữ liệu thì dữ liệu là điểm giao nhau.
http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Types/ClipType.htm
Một số phương pháp bạn sẽ thấy hữu ích cho việc này.
private static int scale = 1000; //your desired precision
public static List<List<IntPoint>> ConvertToClipperPolygons(GraphicsPath path)
{
var Polygon = new List<IntPoint>();
var Polygons = new List<List<IntPoint>>();
var it = new GraphicsPathIterator(path);
it.Rewind();
bool isClosed;
int startIndex;
int endIndex;
for (int i = 0; i < it.SubpathCount; i++)
{
var PointCount = it.NextSubpath(out startIndex, out endIndex, out isClosed);
var Points = new PointF[PointCount];
var Types = new byte[PointCount];
it.CopyData(ref Points, ref Types, startIndex, endIndex);
Polygons.Add(new List<IntPoint>(Points.Select(x => new IntPoint(Convert.ToInt64(x.X * scale), Convert.ToInt64(x.Y * scale)))));
}
it.Dispose();
return Polygons;
}
Và để thực hiện một giao
public static GraphicsPath intersect(ref GraphicsPath p1, ref GraphicsPath p2)
{
List<List<IntPoint>> polygonB = ConvertToClipperPolygons(p1);
List<List<IntPoint>> polygons = new List<List<IntPoint>>();
List<List<IntPoint>> polygonA = ConvertToClipperPolygons(p2);
Clipper c = new Clipper();
c.AddPolygons(polygonB, PolyType.ptSubject);
c.AddPolygons(polygonA, PolyType.ptClip);
c.Execute(ClipType.ctIntersection, polygons, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd);
return ConvertClipperToGraphicsPath(polygons);
}
public static GraphicsPath ConvertClipperToGraphicsPath(List<List<IntPoint>> path)
{
GraphicsPath returnPath = new GraphicsPath();
for (int i = 0; i < path.Count; i++)
{
returnPath.AddPolygon(ToPointList(path[i]).ToArray());
}
return returnPath;
}
private static List<PointF> ToPointList(List<IntPoint> pointList)
{
List<PointF> newList = new List<PointF>();
foreach (IntPoint pt in pointList)
{
newList.Add(new PointF(((float)pt.X/(float)scale), ((float)pt.Y/(float)scale)));
}
return newList;
}
Đáng ngạc nhiên, tôi không nhận thấy một sự suy giảm nếu hai bên không giao nhau. Chỉ khi các khu vực giao nhau có một sự suy giảm đáng chú ý. (Tuy nhiên, các vùng tôi đang thử nghiệm không phức tạp lắm). – user2428118