Bu eski bir soru, ama çözümümü de paylaşacağımı düşündüm. Region.IsEmpty() bir Grafik içeriği gerektirir ve benim anlayışım sadece piksel hassas vuruş testi yapmak için tasarlanmıştır. Bu birçok durum için ideal değildir. Çok daha iyi bir çözüm, Clipper kütüphanesinin Angus Johnson tarafından kullanılmasıdır. Benim tecrübemde bu hızlı test edilmiş bir kütüphanedir. Kendi hassaslığınızı sağlayabilir ve son derece karmaşık çokgenler kullanır.
http://www.angusj.com/delphi/clipper.php
C# uygulaması vardır. Yapmanız gereken şey, System.Drawing.Region yöntemi gibi bir kesişim işlemi gerçekleştirmektir. Ardından işlemin sonucunu inceleyin. Boşsa, kesişme yoktu. Veri içeriyorsa, veriler kesişen noktalardır.
http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Types/ClipType.htm
Bazı yöntemler bunun için kullanışlı bulur. iki kesişen değilse
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;
}
Ve bir kesişme Şaşırtıcı
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;
}
gerçekleştirmek için, ben bir yavaşlama fark etmiyorum. Sadece bölgeler kesiştiği zaman kayda değer bir yavaşlama olur. (Test ettiğim bölgeler özellikle karmaşık değil.) – user2428118