C#中如何绘制Clipper库生成的偏移多边形(DrawPolygons不存在)
问题解决方法
首先明确:DrawPolygons()不是Clipper库、GDI+的内置函数,是网络示例作者自己封装的私有工具方法,没有公开的调用入口,不需要刻意找这个函数的实现,核心只要解决Clipper的IntPoint类型和GDI+坐标类型的转换,直接调用GDI+原生绘制API就能完成效果。
核心转换逻辑
Clipper为了规避浮点计算误差,默认使用整数类型的IntPoint存储坐标,和GDI+用的Point/PointF结构是一一对应的,只需要做简单的值映射即可:
- 如果你传入Clipper的坐标和GDI+像素坐标是1:1对应,直接取IntPoint的X、Y值构造PointF就行
- 如果你为了更高精度给传入Clipper的坐标乘过缩放系数(比如乘100、1000),转换时把X、Y除以对应缩放系数即可
替换DrawPolygons的实现代码
你原有代码还有一个隐藏问题:声明的boundary_point_list是空集合,没有把你存储原多边形顶点的boundary_Points转成IntPoint填入,会导致偏移结果为空。修正后的可直接运行的代码如下:
using Path = List<IntPoint>; using Paths = List<List<IntPoint>>; // 原GDI+多边形绘制逻辑 boundary_path.AddLines(boundary_Points); Region boundary_region = new Region(boundary_path); g.DrawPath(pen1, boundary_path); g.FillPolygon(Brushes.Olive, boundary_Points); // 构造Clipper用的多边形路径 ClipperOffset co = new ClipperOffset(); Path boundary_point_list= new Path(); // 将GDI+的Point数组转为Clipper的IntPoint集合 foreach (Point pt in boundary_Points) { boundary_point_list.Add(new IntPoint(pt.X, pt.Y)); } co.AddPath(boundary_point_list, JoinType.jtRound, EndType.etClosedPolygon); Paths solution = new Paths(); co.Execute(ref solution, -7.0); // 替换原示例中的DrawPolygons(solution, 0x40808080) // 0x40808080对应ARGB半透明灰色,直接构造对应画刷 using (Brush offsetFillBrush = new SolidBrush(Color.FromArgb(0x40, 0x80, 0x80, 0x80))) { foreach (Path singlePolygon in solution) { // 单条多边形的IntPoint转GDI+可用的PointF数组 PointF[] drawPoints = singlePolygon.Select(p => new PointF(p.X, p.Y)).ToArray(); // 调用GDI+原生填充方法完成绘制 g.FillPolygon(offsetFillBrush, drawPoints); // 如果需要给偏移后的多边形加描边,补充下行即可 // g.DrawPolygon(Pens.Gray, drawPoints); } }
注意事项
- 如果偏移后出现多边形方向相反、孔洞填充异常的问题,可以给
FillPolygon方法传入第二个参数FillMode.Alternate或者FillMode.Winding,和Clipper的填充规则对应即可。 - 如果你使用了坐标缩放提升偏移精度,记得转换PointF的时候同步除以缩放系数,保证绘制尺寸正确。
内容的提问来源于stack exchange,提问作者Martin Graupner
相关产品推荐
相关产品推荐

