【发布时间】:2012-01-16 08:20:48
【问题描述】:
我正在尝试使用 Douglas-Peucker 算法减少多边形的顶点 - 这对于线条和路径非常有效。
我的问题是我要优化的多边形是封闭的。选择2个随机相邻点时,优化运行良好 - 除了开始和结束点 - 由于它们是固定的并且无法优化。
有没有好的选择起点的方法?
【问题讨论】:
标签: algorithm optimization polygon
我正在尝试使用 Douglas-Peucker 算法减少多边形的顶点 - 这对于线条和路径非常有效。
我的问题是我要优化的多边形是封闭的。选择2个随机相邻点时,优化运行良好 - 除了开始和结束点 - 由于它们是固定的并且无法优化。
有没有好的选择起点的方法?
【问题讨论】:
标签: algorithm optimization polygon
我会随机选择一个点(例如:所有点列表中的“第一个”点)并找到最远的点。这类似于算法在寻找离线段最远点时的普通步骤。
【讨论】:
我可能完全误解了这里的问题,但听起来您只是想将 Douglas-Peucker 算法 (http://en.wikipedia.org/wiki/Ramer–Douglas–Peucker_algorithm) 应用于多边形。您不能将多边形视为起点和终点相同的线的唯一原因是因为算法要求您让这两个点不同。
所以我建议在多边形上选择两个相距很远的任意点,然后运行 Douglas-Peucker 算法两次,一次用于点之间顺时针方向的路径,一次用于点之间的路径逆时针走。
您的任意点保证在最终解决方案中,否则它会尽可能接近算法的直线近似值。
如果这还不够,您应该搜索 LOD 或细节级别,因为这就是计算机图形学中通常所说的这个问题,尽管您可能会找到一堆关于解决多面体问题的页面相当复杂的树结构,这可能是也可能不是您正在寻找的。
【讨论】:
我在我的 javascript 库中做了类似的事情,在那里我找到了彼此相距最远的两个点,并使用它们来优化多边形。
这里是 sn-p 我相信你可以适应你使用的任何语言:
function polygonPeuckerReduce(path, tolerance) {
var points = [];
if (path.length < 3) {
return points.concat(path);
} else {
var widest = 0.0, startIndex = 0;
// find the widest part of the polygon (only start index is necessary)
for (var i = 0, l = path.length; i < l; i++) {
var point = path[i];
for (var j = i + 1; j < l; j++) {
var distance = point.distanceTo(path[j]);
if (distance > widest) {
startIndex = i;
widest = distance;
}
}
}
// re-order the points with the new starting point (faster method)
points = path.splice(startIndex, path.length).concat(path);
return PEUCKER_INTERNAL(points, tolerance); // the magic
}
}
【讨论】:
另一种可能性是扫描所有三个连续顶点的集合,并选择距离连接其前任和后继顶点的线最远的两个顶点,即选择属于原始数据集中两个最大角的两个顶点。修复这两个顶点,然后将 Douglas-Peucker 应用于中间顶点。
如果您的所有点都间隔很近,这可能会很吵。在这种情况下,您可以从每个输入顶点在两个方向上向外工作,而不是简单地考虑三个顶点的连续集合,使用 Douglas-Peucker 跳过每个方向上不必要的顶点。这将导致更大、更宽的三元组。再次找到距离连接前驱/后继顶点的线最远的两个顶点,修复它们,然后将 Douglas-Peucker 应用于中间顶点。
其他变化是可能的,但这应该比其他答案中描述的“随机”或“最远”提供更好的起点。
【讨论】: