如何高效计算指定面板内多边形间的空白区域?
高效计算面板内多边形间空白区域的实现方案
需求说明
在宽X、高Y的面板中,查找一个或多个多边形之间的空白区域。多边形由依次连接的点列表构成(点1与点2、点2与点3等通过线段连接)。已完成多边形构建的基础代码,需补充高效计算空白区域的逻辑,禁止使用逐点检测等耗时方法。
修正后的基础代码(修复泛型错误+优化资源释放)
原代码存在泛型未指定、手动Dispose冗余等问题,先修正如下:
private void FindEmptySpace() { List<Point> Polygon = new List<Point>(); List<List<Point>> Polygons = new List<List<Point>>(); foreach(Point point in AllPoints) { // using块自动释放Pen资源,无需手动Dispose using(Pen pen = new Pen(Color.Blue, 2)) { MarkerView.CreateGraphics().DrawRectangle(pen, point.X, point.Y, 1, 1); } if(point.X != -10 && point.Y != -10) { Polygon.Add(point); } // 遇到分隔点时,将有效多边形存入列表(需至少3个点构成多边形) if(point.X == -10 && point.Y == -10){ if(Polygon.Count >= 3) Polygons.Add(Polygon); Polygon = new List<Point>(); } } // 调用空白区域计算逻辑 CalculateEmptyRegions(Polygons, MarkerView.Width, MarkerView.Height); }
核心空白区域计算逻辑(基于Region布尔运算)
利用.NET自带的Region类实现高效的区域加减运算,底层为几何算法而非逐点检测,性能更优:
private void CalculateEmptyRegions(List<List<Point>> polygons, int panelWidth, int panelHeight) { // 初始化空白区域为整个面板 Region emptyRegion = new Region(new Rectangle(0, 0, panelWidth, panelHeight)); foreach(var polygonPoints in polygons) { using(GraphicsPath polygonPath = new GraphicsPath()) { // 将多边形点转换为图形路径 polygonPath.AddPolygon(polygonPoints.ToArray()); // 从空白区域中排除当前多边形 emptyRegion.Exclude(polygonPath); } } // 示例:将空白区域用灰色填充显示 using(Graphics g = MarkerView.CreateGraphics()) { using(Brush fillBrush = new SolidBrush(Color.LightGray)) { g.FillRegion(fillBrush, emptyRegion); } } // 若需获取空白区域的具体边界,可通过GetRegionScans提取扫描矩形 Matrix transformMatrix = new Matrix(); RectangleF[] emptyAreaScans = emptyRegion.GetRegionScans(transformMatrix); // 可进一步将扫描矩形转换为多边形边界,按需处理 }
关键注意事项
- 多边形有效性:必须确保每个多边形至少包含3个点,否则
AddPolygon会抛出异常。 - 资源管理:所有实现
IDisposable的对象(如GraphicsPath、Region、Brush)必须用using块包裹,避免内存泄漏。 - 坐标一致性:确保面板坐标与多边形点的坐标系统一致(默认以左上角为原点)。
内容的提问来源于stack exchange,提问作者NEON_GOD
相关产品推荐
相关产品推荐

