多边形差异 – 来自Clipperlib的奇怪结果

我试图从一组轮廓创建等面积多边形(“甜甜圈”)。 这是一个过程:

  1. 生成轮廓。
  2. 将轮廓分类为树结构,使得在特定轮廓内保持的所有轮廓都是该轮廓的子轮廓。
  3. 对于每个轮廓,使用Clipperlib对其所有子项执行差异运算。

得到的多边形和孔构成等区域“甜甜圈”。 然后可以将这些等区域渲染为等高线图,或用于其他目的。 请注意,如果我想要做的只是渲染轮廓,我可以在初始排序后停止并按顺序渲染轮廓,这样最内部渲染在顶部。 我确实需要实际的区域。

首先 – Clipperlib是一个很棒的图书馆,我非常乐意为此付出很多钱 – 感谢安格斯!

我的问题是,在某些情况下,我似乎从差异操作中得到了一些奇怪的结果 – 我怀疑这可能是我的用户错误,所以我将说明问题:

图像一

此图像显示两个多边形 – 主题以红色标出,孩子用蓝色填充。 我希望从这个主题中减去孩子们。 注意鼠标指针附近的小区域。 我期望从这个差异是两个外部多边形 – 鼠标指针附近的小多边形和大的多边形。 我还希望所有的“岛屿”都是第二个大的多边形内的洞。

我实际得到的是两个outers(如预期的那样),每个都与儿童(洞)相关联:

图像二

在此处输入图像描述

在第二个图像中,鼠标指针附近的微小多边形是“外部”,所有其他填充的多边形都是属于它的“孔”。 请注意,我在两个图像中都显示了两种解决方案的轮廓 – 只关注填充的多边形。

我正在使用第一个图像中的红色多边形作为主题执行clipperlib,并将所有子项作为剪辑执行。 剪辑类型是ctDifference(我也尝试过具有相同结果的Xor – 它们应该是,因为所有孩子都在主题内)。 我正在请求PolyTree,它有两个Childs。 我正在使用c#库,并尝试过v6。

在一个层面上,我需要的结果都在那里 – 所有的“洞”都被指定为这样,问题是许多这些洞被返回作为图像右上方的微小外部区域的子项。 我是否错误地使用ClipperLib读取PolyTree,或者这个结果是错误的?

进一步说明 – 我注意到新的ClipperLib(v6)现在接受Z值。 我现在想知道是否有比我用于从给定的无序轮廓线集合生成这些等区域更好的方法?

谢谢,马特

编辑:我已经在文本文件中上传了多边形的原始数据。

链接在这里

该文件将主题多边形作为第一组顶点,然后是每个子项。 每个多边形在单行上表示为X / Y对,每个多边形之间有一个换行符。

在第二个图像中,鼠标指针附近的微小多边形是“外部”,所有其他填充的多边形都是属于它的“孔”。 请注意,我在两个图像中都显示了两种解决方案的轮廓 – 只关注填充的多边形。

这听起来像某个地方有一个错误,但没有原始数据很难分辨。

此外,这不是Clipper支持的最佳位置,还有一个讨论论坛和一个在SourceForge 报告可疑错误的地方。 无论如何,现在最好在这里发布您的原始数据(尽可能少地请在重现问题的同时)。

编辑:

好的,我已经查看了数据,我不明白为什么你相信……“所有其他填充的多边形都是属于它的”洞“。

PolyTree solutiontree = new PolyTree(); cpr.Execute(ClipType.ctDifference, solutiontree, PolyFillType.pftNonZero, PolyFillType.pftNonZero); solution = new Polygons(solutiontree.ChildCount); foreach (PolyNode pn in solutiontree.Childs) solution.Add(pn.Contour); 

只需使用上面的代码片段过滤解决方案PolyTree的顶层PolyNodes(以及顶级节点必须是’outers’),这就是我得到的(解决方案是绿色阴影)……

在此处输入图像描述

从这个结果来看,“鼠标指针附近的微小多边形”可以拥有其他多边形。 话虽如此,解决方案中仍然存在漏洞,因此某处需要修复漏洞。

编辑2:我找到并修复了错误并将Clipper版本6.0.2上传到SourceForge存储库 。 在我正式更新主Zip包之前,我需要做更多的错误检查。

编辑3:显然仍然不是正确的。

编辑4:我认为我最终确定了这个错误(参见SourceForge存储库中的修订版420)。 跟进那里 。