我正在寻找一种非常简单的算法来计算多边形的交/裁剪。
即,给定多边形P
,Q
,我希望找到包含在P
和Q
中的多边形T
,并且我希望T
是所有可能多边形中最大的。
我不介意运行时间(我只有几个非常小的多边形),我也可以承受多边形交的近似解(即具有更少点数但仍包含在多边形交中的多边形)。
但对我来说真正重要的是算法要简单(测试便宜),最好是短小精悍的代码。
编辑:请注意,我希望获得代表交集的多边形。我不仅需要两个多边形是否相交的布尔答案。
我正在寻找一种非常简单的算法来计算多边形的交/裁剪。
即,给定多边形P
,Q
,我希望找到包含在P
和Q
中的多边形T
,并且我希望T
是所有可能多边形中最大的。
我不介意运行时间(我只有几个非常小的多边形),我也可以承受多边形交的近似解(即具有更少点数但仍包含在多边形交中的多边形)。
但对我来说真正重要的是算法要简单(测试便宜),最好是短小精悍的代码。
编辑:请注意,我希望获得代表交集的多边形。我不仅需要两个多边形是否相交的布尔答案。
我理解原帖的作者正在寻找一个简单的解决方案,但不幸的是,真的没有简单的解决方案。
尽管如此,我最近创建了一个开源免费剪切库(用Delphi、C++和C#编写),可以剪切所有类型的多边形(包括自交多边形)。这个库使用起来非常简单:https://github.com/AngusJohnson/Clipper2
function get_polygon_intersection($arr, $user_array)
{
$maxx = -999; // choose sensible limits for your application
$maxy = -999;
$minx = 999;
$miny = 999;
$intersection_count = 0;
$not_intersected = 0;
$sampling = 20;
// find min, max values of polygon (min/max variables passed as reference)
get_array_extent($arr, $maxx, $maxy, $minx, $miny);
get_array_extent($user_array, $maxx, $maxy, $minx, $miny);
$inc_x = $maxx-$minx/$sampling;
$inc_y = $maxy-$miny/$sampling;
// see if x,y is within poly1 and poly2 and count
for($i=$minx; $i<=$maxx; $i+= $inc_x)
{
for($j=$miny; $j<=$maxy; $j+= $inc_y)
{
$in_arr = pt_in_poly_array($arr, $i, $j);
$in_user_arr = pt_in_poly_array($user_array, $i, $j);
if($in_arr && $in_user_arr)
{
$intersection_count++;
}
else
{
$not_intersected++;
}
}
}
// return score as percentage intersection
return 100.0 * $intersection_count/($not_intersected+$intersection_count);
}
我解决同样问题的方式:
IntervalTrees
或LineSweepAlgo
找到相交的线段GrahamScanAlgo
找到相邻顶点的闭合路径DinicAlgo
进行交叉引用以消除它们注意:我的情况不同,因为多边形有一个共同的顶点。但希望这可以帮助到您。
我没有非常简单的解决方案,但以下是真正算法的主要步骤:
然后您将得到多边形相交解决算法的原始结果。通常,您会根据每个区域的绕数选择一些区域。搜索“多边形绕数”以了解其说明。
如果您想将此O(N²)算法转换为O(N·logN)算法,则必须完全相同地执行此操作,只是在线扫描算法内部执行。搜索“Bentley Ottman算法”。内部算法将是相同的,唯一的区别是您将比较的边数减少,在循环内部。
如果您不关心可预测的运行时间,可以尝试先将多边形分割为凸多边形的并集,然后成对计算子多边形之间的交集。
这将给您一组凸多边形,使它们的并集恰好是起始多边形的交集。
这可能会根据多边形的不同而有很大的近似,但以下是一种可行的方法:
尽管如此,由于对多边形的任何变换都同样适用于重心,因此这种方法应该非常高效,只需要计算一次中心节点距离。