3

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

  1. 生成轮廓。
  2. 将等高线排序为树状结构,以使特定等高线内的所有等高线都是该等高线的子代。
  3. 对于每个轮廓,使用 Clipperlib 对其所有子项执行差异操作。

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

首先 - Clipperlib 是一个很棒的库,我很乐意花大价钱购买它 - 感谢 Angus!

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

图一

这张图片显示了两个多边形 - 主体用红色勾勒出来,孩子们用蓝色填充。我想从主题中减去孩子。注意鼠标指针附近的小区域。我对这个差异的期望是两个外部多边形 - 靠近鼠标指针的小一个和大一个。我进一步希望所有“岛屿”都是第二个大多边形内的洞。

我实际上得到的是两个外部(如预期的那样),每个外部都有孩子(洞):

图二

在此处输入图像描述

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

我正在使用第一张图像中的红色多边形作为主题执行clipperlib,并将所有子项作为剪辑。剪辑类型是 ctDifference (我也尝试过 Xor 得到相同的结果 - 他们应该是这样,因为所有孩子都在主题内)。我要一个 PolyTree 回来,它有两个孩子。我正在使用 c# 库,并且也尝试过 v6。

在一个层面上,我需要的结果都在那里——所有的“洞”都被指定为这样,问题是这些洞中有许多是作为图像右上角的微小外部区域的子级返回的。我是在错误地阅读 PolyTree,错误地使用 ClipperLib,还是这个结果完全错误?

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

谢谢,马特

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

链接在这里

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

4

1 回答 1

4

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


这听起来像是某处存在错误,但如果没有原始数据很难判断。

此外,这不是 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 的顶级 PolyNode(并且顶级节点必须是“外部”),这就是我得到的(解决方案为绿色阴影)......

在此处输入图像描述

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

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

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

编辑 4: 我想我终于解决了这个错误(参见 SourceForge 存储库中的修订版 420)。跟进那里

于 2013-11-05T19:51:38.983 回答