Math 如何组合复杂多边形?

Math 如何组合复杂多边形?,math,geometry,union,Math,Geometry,Union,给定两个多边形: POLYGON((1 0, 1 8, 6 4, 1 0)) POLYGON((4 1, 3 5, 4 9, 9 5, 4 1),(4 5, 5 7, 6 7, 4 4, 4 5)) 如何计算并集(组合多边形) 使用SQL server生成联合,但我需要在代码中实现同样的功能。我正在寻找一个数学公式或代码的任何语言,暴露了实际的数学例子。我正在尝试制作地图,将国家动态地组合成区域。我在这里问了一个相关的问题:你需要。删除这些点后,可以将一组“外部”点插入另一组。您的插入点(如

给定两个多边形:

POLYGON((1 0, 1 8, 6 4, 1 0))
POLYGON((4 1, 3 5, 4 9, 9 5, 4 1),(4 5, 5 7, 6 7, 4 4, 4 5))
如何计算并集(组合多边形)


使用SQL server生成联合,但我需要在代码中实现同样的功能。我正在寻找一个数学公式或代码的任何语言,暴露了实际的数学例子。我正在尝试制作地图,将国家动态地组合成区域。我在这里问了一个相关的问题:

你需要。删除这些点后,可以将一组“外部”点插入另一组。您的插入点(如右图中箭头所在的位置)是您必须从输入集中删除点的位置。

问得好!我以前从未尝试过,但现在我要尝试一下

首先:你需要知道这两个形状在哪里重叠。为此,您可以查看多边形A中的每条边,并查看其相交位置和多边形B中的边。在本例中,应该有两个交点


然后:使联合的形状。可以获取A和B中的所有顶点以及交点,然后排除最终形状包含的顶点。要找到这些点,看起来你可以找到A在B内的任何顶点,以及B在A内的任何顶点。

在对国家进行分组时,我希望没有重叠——你可以采用一种非常简单的算法来寻找共享顶点——一个简单的视图是在一个多边形上迭代点,查看它是否位于任何其他多边形上,并共享相同的下一个或上一个点以查看是否存在匹配。然后只需删除共享顶点即可创建并集

试试。

我看到的使用BSP树的解决方案如下所述


基本上,它描述了多边形a中位于多边形B内部的边的并集的相交(包括部分边,并使用a计算)。然后,您可以将A/B定义为(~A/\~B),其中~表示多边形的反向缠绕,/表示并集,/\表示相交。

这是一个非常好的问题。不久前,我在c#上实现了相同的算法。该算法构造两个多边形的公共轮廓(即构造无孔的并集)。给你


第一步。创建描述多边形的图形。 输入:第一个多边形(n个点),第二个多边形(m个点)。输出:图形。顶点-交点的多边形点

我们应该找到十字路口。迭代两个多边形[O(n*m)]中的所有多边形边,并找到任何交点

  • 如果找不到交点,只需添加顶点并将其连接即可 到了边缘

  • 如果发现任何交叉点,请按长度将其排序到起点,然后添加所有交叉点 顶点(起点、终点和交点)并连接它们(已在 排序顺序)到边缘。

第二步。检查构造图 如果在构建图形时未找到任何交点,则存在以下条件之一:

  • Polygon1包含polygon2-返回Polygon1
  • Polygon2包含polygon1-返回Polygon2
  • 多边形1和多边形2不相交。返回polygon1和polygon2 第三步。找到左下顶点。 找到最小的x和y坐标(minx,miny)。然后找到(minx,miny)和多边形点之间的最小距离。此点将是左底点

    第四步。构造公共轮廓。 我们从左下角点开始遍历图形,然后继续遍历,直到回到它为止。开始时,我们将所有边标记为未访问。在每次迭代中,您应该选择下一个点并将其标记为已访问

    要选择下一个点,请选择沿逆时针方向具有最大内角的边

    我计算两个向量:当前边的向量1和下一个未访问边的向量2(如图所示)

    对于向量,我计算:

  • 标量积(点积)。它返回与向量之间的角度相关的值
  • 向量积(叉积)。它返回一个新的向量。如果这个的z坐标 向量是正的,标量积给我直角 逆时针方向。否则(z坐标为负),I 计算矢量之间的“获取角度”(get angle)为标量的360度角 产品
  • 结果,我得到了一条具有最大角度的边(和对应的下一个顶点)

    我将每个经过的顶点添加到结果列表中。结果列表是并集多边形。

    评论
  • 该算法允许我们将多个多边形合并为一个多边形 使用多边形对迭代应用
  • 如果有一条由许多贝塞尔曲线和直线组成的路径,则应首先展平该路径

  • 我今天需要解决同样的问题,并使用以下库找到了解决方案:


    它有很多语言实现,包括Java、Obj-C、C#、Lua、python等等。

    这是一个富有挑战性但又易于理解的主题,经常会出现 名称为“多边形上的正则化布尔运算” 你可以看看 , 其中包括下图 (来自), 与粉红联盟,OP的组合:



    这是一个很老的问题,但是Boost的函数对我来说很有用

    请参见下面的片段:

    #include <iostream>
    #include <vector>
    
    #include <boost/geometry.hpp>
    #include <boost/geometry/geometries/point_xy.hpp>
    #include <boost/geometry/geometries/polygon.hpp>
    
    #include <boost/foreach.hpp>
    
    
    int main()
    {
        typedef boost::geometry::model::polygon<boost::geometry::model::d2::point_xy<double> > polygon;
    
        polygon green, blue;
    
        boost::geometry::read_wkt(
            "POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))", green);
    
        boost::geometry::read_wkt(
            "POLYGON((5 5, 5 15, 15 15, 15 5, 5 5))", blue);
    
        std::vector<polygon> output;
        boost::geometry::union_(green, blue, output);
    
        int i = 0;
        std::cout << "green || blue:" << std::endl;
        BOOST_FOREACH(polygon const& p, output)
        {
            std::cout << i++ << ": " << boost::geometry::area(p) << std::endl;
    
            for (int i = 0; i < p.outer().size(); i++)
            {
                std::cout << p.outer().at(i).x() << " " << p.outer().at(i).y() << std::endl;
            }
        }
    
    
    
        return 0;
    }
    
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    int main()
    {
    typedef boost::geometry::model::polygon;
    多边形绿色、蓝色;
    boost::geometry::read_wkt(
    “多边形((0,0,10,10,10,10,0,0))”,绿色);
    boost::geometry::read_wkt(
    “多边形((5,5,15,15,15,5,5))”,蓝色);
    std::矢量输出;
    boost::geometry::union(绿色、蓝色、输出);
    int i=0;
    
    std::cout我也遇到过同样的问题,我用以下方法解决了这个问题

    Cython包装器用于Angus Johnson剪裁库的C++翻译(V..4.4.2)

    +1
    pc = pyclipper.Pyclipper()
    def get_poly_union(polygons):
        pc.AddPaths(polygons, pyclipper.PT_SUBJECT, True)
        solution = pc.Execute(pyclipper.CT_UNION, pyclipper.PFT_NONZERO, pyclipper.PFT_NONZERO)
        return solution[0]
    
    print_image = image.copy()
    solution = get_poly_union(polygons_array) 
    #polygons_array=[polygon,polygon,polygon, ...,polygon] and polygon=[point,point,point...,point]
    
    cv2.drawContours(print_image, [np.asarray(solution)], -1, (0, 255, 0), 2)
    
    plt.imshow(print_image)