我正在使用多边形的质心在地图应用程序中附加标记。这对于凸多边形非常好,对于许多凹多边形非常有用。
然而,一些多边形(香蕉,甜甜圈)显然不会产生预期的结果:在这些情况下,质心在多边形区域之外。
是否有人知道更好的方法在任何多边形区域(可能包含孔!)中找到合适的点来附加标记?
答案 0 :(得分:5)
一种方法是生成并细化多边形的skeleton,然后使用骨架的中点放置标记(如果是文本,则正确定位文本)。这适用于大多数形状,包括带孔,香蕉形或蝌蚪形新月形。
CGAL库有一个2D Straight Skeleton and Polygon Offsetting模块,或者你可以use PostGIS。
答案 1 :(得分:3)
要重新评论ChristopheRoussy的评论,我们可能会寻找多边形内部的最大圆圈。
最大的圆是不能再生长的圆,因为它接触三个顶点或边(如果它只触及两个,它可以变大或只是移动直到它触及第三个)。
因此,如果您有很少的顶点,您可以枚举所有可能的顶点/边三元组,找到每个顶点,然后选择最大的顶点。
但它需要创建四个功能:
所有这些都是可能的,但可能需要一些努力。
答案 2 :(得分:2)
我不知道如何为任何可能的形状解决这个问题(并没有做大量的计算),但也许对于你所展示的更简单的形状:
https://en.wikipedia.org/wiki/Force-directed_graph_drawing
启发式:这可能会在一段时间后收敛到合理的近似值
另一种方法可能是根据形状的性质使用多种算法(就像甜甜圈的另一种算法......)。也许还可以依靠衡量“最胖”的方法。第一节?
恕我直言会在数学论坛上问这个问题。
答案 3 :(得分:2)
找到极端纵坐标并在中间画一条水平线。保证穿过多边形。
找到与两侧的交点并通过增加横坐标对它们进行排序。在两个交叉点的中间选择一个点。
这是O(N + K Log K)过程,其中K是交叉点的数量(通常是非常小的偶数)。非常直接的写作。
为了增加漂亮放置的几率,您可以尝试三个横向而不是一个挑选最长的交叉点。
答案 4 :(得分:1)
要获得标记的分数,我将使用伊夫·达乌斯特(Yves Daoust)的方法。
要获得一个可靠的“在任何带孔的多边形内”的点,我将使用可靠的库(例如OpenGL的GLUtessellator)将多边形分割成三角形,然后得到面积最大的三角形的质心。
如果我有时间进行开发和测试,并且想要良好的性能,那么我将使用一种混合方法:首先使用Yves Daoust的方法来获取一些候选点,然后测试候选者以查看它们是否在多边形内。如果所有候选人均不及格,则退回到较慢的可靠方法(例如GLUtesselator)。
答案 5 :(得分:0)
for (int i = 0; i < n; /*++i*/) {
p = RandomPointInsideConvexHull();
if (IsInsidePolygon(p)) {
++i;
d = DistanceToClosestEdge(p);
if (d > bestD) {
bestP = p;
}
}
}
运行此循环后,您将按bestP
近似解决方案。 n
是要选择的参数。如果你想要更准确的结果你可以重新开始搜索,但是现在你可以在bestP
附近挑选一个点,而不是在bestD / 5
附近选择一个点,而不是在// TODO: complete program
console.log(calculate(4, "+", 6)); // Must show 10
console.log(calculate(4, "-", 6)); // Must show -2
console.log(calculate(2, "*", 0)); // Must show 0
console.log(calculate(12, "/", 0)); // Must show Infinity
附近选择一个点(这次你不要不需要检查随机点是否在多边形内。