【问题标题】:Check position and merge polygons with delphi用delphi检查位置和合并多边形
【发布时间】:2013-02-22 11:12:20
【问题描述】:

在我的应用程序中,我有 2 个或更多多边形,一个多边形可以在其他多边形的内部或外部(全部在内部或全部在外部)。 我必须这样做:

  1. 检查一个多边形是否在其他多边形的内部(所有内部没有交叉点);
  2. 如果点 1 为真“合并多边形”;

要了解我的“合并多边形”,请看图:

如您所见,有 2 个多边形:A-B-C-D-A 和 1-2-3-1,我需要找到 2 个点(A-B-C-D-A 一个点,1-2-3-1 一个点)然后用 2 条线连接,新线不得与多边形线相交。

有没有关于这类问题的理论可以更快地找到最佳解决方案?

【问题讨论】:

  • 请不要将 JPG 用于插图 - 使用 PNG(或者,如果可能,最好使用 SVG)。
  • 好的,下次我会用PNG或SVG。
  • 你的多边形总是凸的吗?
  • 不,也可以是凹的,但不能相交。

标签: geometry polygons


【解决方案1】:

另一个多边形中的多边形

由于您的多边形要么全部在内部,要么全部在外部,因此可以简单地将其简化为测试多边形的一个点是在另一个多边形内部还是外部。这是一个众所周知的问题,有多种解决方案:Point in polygon

合并多边形

您的问题没有唯一的解决方案。对我来说最明显的方法是找到两个角,每个多边形的一个角比其他任何一对角都更靠近。

【讨论】:

    【解决方案2】:

    要获得最佳性能,您应该根据自己的数据比较不同的算法。我比较了一些 Point-In-Polygon 算法,我发现 Ray-Casting 提供了最好的性能,here's 是一个比较。你可以找到一个写得很好的Ray-Casting算法实现here

    这是一个快速而简单的部分,在下一步你想要合并两个多边形。如果多边形是凸的,您可以连接两个更近的顶点,但是由于您说它们可能是凹的(甚至是凸多边形的边缘上有额外的顶点),因此更近的角将不起作用。例如:

    您应该从每个多边形中选择一个顶点,使其连接线不与多边形的任何边相交。要找到两条线的交点,您可以这样做:

    function Zero(const Value: Double): Boolean;
    const
      Epsilon = 1E-10;
    begin
      Result := Abs(Value) < Epsilon;
    end;
    
    function IntersectLines(const X11, Y11, X12, Y12, X21, Y21, X22, Y22: Double;
      out X, Y: Double): Boolean;
    var
      A1, B1, C1, A2, B2, C2, D: Double;
    begin
      A1 := Y12 - Y11;
      B1 := X11 - X12;
      C1 := A1 * X11 + B1 * Y11;
    
      A2 := Y22 - Y21;
      B2 := X21 - X22;
      C2 := A2 * X21 + B2 * Y21;
    
      D := A1 * B2 - A2 * B1;
      if Zero(D) then
        Result := False // Lines are parallel
      else
      begin
        X = (B2 * C1 - B1 * C2) / D;
        Y = (A1 * C2 - A2 * C1) / D;
      end;
    end;
    

    但请注意,仅找到交点并不意味着所选顶点不正确,因为我们正在处理线段,因此交点应该在线段内。要找出这一点,您可以检查该点是否在线段的边界框内。例如在这个插图中,1 和 2 是选定的顶点,3 是它们的交叉线与边的交点,但 3 不在 1 和 2 的覆盖边界框内。

    您应该注意到,每对选定顶点的交叉线将至少穿过边界框内每个多边形的两条边(在选定顶点上相交的边),因此边界框不应包含它的边界。

    之后,您应该将外部多边形与其选定的顶点分开,并在它们之间插入内部多边形的重定向顶点。

    最后,我应该说:是的!有很多关于所有这些的理论,但你应该找到自己的。正如您所说,一个多边形都在另一个多边形内,这意味着它们是系统生成的,甚至是像字符边界一样预定义的。然后 您也许可以更改所有讨论过的算法,以针对您自己的情况获得更好的性能。

    【讨论】:

      【解决方案3】:

      我们使用一种简单的蛮力方法来查找其中的任何点是否是多边形。

      创建一个画布,用白色填充它并用蓝色绘制多边形。现在查看您感兴趣的任何点的像素颜色,以确定它是否在多边形内。

      如果您想知道一个画布是否完全包含在另一个画布中,而不是创建第二个画布并在另一个画布上绘制一个,两者都是蓝色的,然后比较它们是否相同。

      在计算上这不是最有效的,但它是完全准确的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-08-08
        • 2017-02-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-17
        相关资源
        最近更新 更多