给定两个多边形:
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))
如何计算联合(组合多边形)?
Dave的示例使用SQL Server生成联合,但是我需要在代码中完成相同的操作。我正在寻找可以公开实际数学的任何语言的数学公式或代码示例。我正在尝试制作将国家动态地组合成地区的地图。我在这里问了一个相关的问题:对地理形状进行分组
Answers:
这个问题问得好。我前一段时间在c#上实现了相同的算法。该算法构造两个多边形的公共轮廓(即构造不带孔的并集)。这里是。
输入:第一个多边形(n个点),第二个多边形(m个点)。输出:图形。顶点-相交点的多边形点。
我们应该找到路口。遍历两个面[O(n * m)]中的所有面,并找到任何交点。
如果找不到相交,只需添加顶点并将其连接到边即可。
如果找到任何相交,则按长度对其起点进行排序,添加所有顶点(起点,终点和相交)并将其连接(已按排序顺序)到边缘。
如果在构建图形时未找到任何交点,则我们具有以下条件之一:
找到最小的x和y坐标(minx,miny)。然后找到(minx,miny)与多边形点之间的最小距离。该点将是左下角。
我们从左下角开始遍历该图,并继续直到回到该图为止。在开始时,我们将所有边缘标记为未访问。在每次迭代中,您应该选择下一个点并将其标记为已访问。
要选择下一个点,请选择一个沿逆时针方向具有最大内角的边。
我计算了两个向量:当前边缘的vector1和每个下一个未访问边缘的vector2(如图所示)。
对于向量,我计算:
结果,我得到了具有最大角度的边(以及对应的下一个顶点)。
我将每个传递的顶点添加到结果列表中。结果列表是联合多边形。
您需要确定哪些点位于其中。删除这些点之后,可以将一组“外部”点插入到另一组中。您的插入点(例如,右侧图片中的箭头所在的位置)是您必须从输入集中删除点的位置。
好问题!我以前从未尝试过,但是现在我会尝试一下。
首先:您需要知道这两个形状在哪里重叠。为此,您可以查看多边形A中的每条边,并查看它们相交的位置以及多边形B中的边。在此示例中,应该有两个相交点。
然后:制作并集形状。您可以获取A和B中的所有顶点以及相交点,然后排除最终形状所包含的顶点。为了找到这些点,您似乎可以找到位于B内的A的任何顶点,以及位于A内的B的任何顶点。
将国家/地区分组时,我希望不会有重叠-您可以采用一种相当幼稚的算法来查找共享顶点-一个简单的视图是遍历一个多边形上的点,看看它是否在其他任何多边形上,并共享相同的下一个或上一个点,以查看是否存在匹配项。然后只需删除共享顶点即可创建并集
我今天需要解决同样的问题,并找到具有以下lib的解决方案:http : //www.cs.man.ac.uk/~toby/alan/software/。
这里有很多语言实现包括Java,Obj-C,C#,Lua,python等。
这是一个很老的问题,但是Union_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;
}
我遇到了同样的问题,并通过以下方式解决了该问题
Cython包装器,用于Angus Johnson's Clipper库的C ++翻译(版本6.4.2) https://github.com/fonttools/pyclipper
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)