【问题标题】:How can I split a Polygon by a Line?如何按线分割多边形?
【发布时间】:2011-04-07 03:01:33
【问题描述】:

如下图,

是否可以用一条线分割多边形? (分成两个多边形)。如果这条线没有完全穿过多边形,它就会失败。

这可能吗?如果是这样,我该怎么做?

【问题讨论】:

    标签: algorithm split polygon


    【解决方案1】:

    1994 年,George Vanecek 在 3D 中为此制定了一个解决方案,并在 Graphic Gems V “平面多边形的空间划分”中发表了该解决方案。源代码仍然在Graphic Gems Repository 中提供。

    最近,David Geier 发布了 Vanecek 算法的 2D 实现,并对该算法进行了解释。见David's Blog: Splitting an arbitrary polygon by a line

    【讨论】:

      【解决方案2】:

      这是可能的,但是如果多边形不是凸面的,那么将它分割成一条线可能会导致两个以上的多边形。

      遍历多边形边,并为每条边确定它是否与线相交。找到第一个这样做的边缘。继续遍历,直到找到另一个这样的边,但是将沿途遇到的每个边添加到一个新的多边形(包括第一条边的一部分,该部分被“这一边”上的线分割,最后一条边也是如此)。最后,为新多边形添加闭合边。现在继续处理边缘 - 在线的另一侧,以相同的方式创建另一个多边形。您现在有两个多边形穿过这条线。如果你小心的话,同样的技术也可以将一个非凸多边形分割成多个多边形。

      注意一些极端情况,例如穿过多边形顶点的线,以及根本不与多边形相交的线。

      编辑:正如 xan 指出的那样,这不能正确处理所有非凸情况。这可以通过对算法进行小的修改来解决。在如上所述添加闭合边之前,您必须首先检查原始多边形的任何其他边是否会与该闭合边相交;如果是这样,您只关闭该边缘并从该点继续处理更多边缘。

      【讨论】:

      • 谢谢。这可能是我一有时间就会做的事情
      • 我不认为该技术如此容易扩展到凹多边形。考虑用一条垂直线分割字母 C 的轮廓。在左侧,您会看到两个重叠的半圆盘多边形。
      • xan,是的,这是另一个需要处理的情况。当您越过分割线时,您需要检查您是否不在之前创建的多边形内;或者更确切地说,确保您合成的边缘不会跨越另一个边缘。
      【解决方案3】:

      我最近不得不这样做。如您的图表所示,仅行走多边形不适用于凹多边形。下面是我的算法草图,灵感来自Greiner-Hormann 多边形裁剪算法。分割比多边形裁剪更容易也更难。更容易,因为您只裁剪一条线而不是矩形或另一个多边形;更难,因为你需要保持双方。

      Create an empty list of output polygons
      Create an empty list of pending crossbacks (one for each polygon)
      Find all intersections between the polygon and the line.
      Sort them by position along the line.
      Pair them up as alternating entry/exit lines.
      Append a polygon to the output list and make it current.
      Walk the polygon. For each edge:
          Append the first point to the current polygon.
          If there is an intersection with the split line:
              Add the intersection point to the current polygon.
              Find the intersection point in the intersection pairs.
              Set its partner as the crossback point for the current polygon.
              If there is an existing polygon with a crossback for this edge:
                  Set the current polygon to be that polygon.
              Else
                  Append a new polygon and new crossback point to the output lists and make it current.
              Add the intersection point to the now current polygon.
      

      【讨论】:

        【解决方案4】:

        您只需要一个多边形裁剪算法。您可以在此处查看概览: Polygon clipping 我认为那里有很多你可以学习的实现。

        【讨论】:

          【解决方案5】:

          完全有可能。我假设您为此使用 Java2d。您在其中找到了一种称为 intersects 的方法。使用它你可以做到这一点。

          您可能必须修改多边形的this 实现,并编写另一个 intersects 方法,该方法传递一个 Line2D 对象并对其进行自定义,以便它传递一个数组多边形(可能是因为相同的线切割可以产生无限多边形 - 假设一个之字形多边形)或空值。

          【讨论】:

          • 感谢您的回复,但我什至不知道该怎么做(涉及的数学)。它可能与与多边形的每条线相交的线有关。 (并像那样分割形状)。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-05-12
          • 1970-01-01
          • 2020-02-08
          相关资源
          最近更新 更多