最近我一直在考虑如何将复杂多边形转换为非复杂多边形。这是怎么做到的?
这是我想要做的事情:
当我完成时,我将最终使用JavaScript,但任何形式的解决方案都很好(语言,算法或简单的英语)。
答案 0 :(得分:6)
我会使用与手工绘制多边形时相同的启发式方法(这可能不是用于对多边形进行caluclaute的最有效的方法,但可能最容易理解/实现)。
Here is an example。注意:它没有优化。
答案 1 :(得分:3)
我认为最简单的方法是执行plane sweep来检测所有边缘交叉点。增加基本的平面扫描算法实现来维护并不困难 最外层的边界,这就是你想要的。几乎每个textbook on computational geometry都能很好地解释这一点。
答案 2 :(得分:1)
您应该维护每个交叉点的事件边缘列表。
然后永远选择边缘(外出),它与前一个(入射)边缘具有最小角度(逆时针)。
答案 3 :(得分:1)
这是一个迟到的答案,但可以使用Javascript Clipper Library完成。所需的操作是简化(内部使用Union操作),它删除了边(s)穿过其他边的自交叉。
请注意! Javascript Clipper 5无法确保在所有情况下解决方案仅包含真正简单的多边形。这种特殊情况就是顶点接触边缘。 Clipper 6(Javascript版尚未准备好)也可以处理这些特殊情况。
您可以使用Javascript Clipper Main Demo玩Clipper。单击“多边形 - 自定义”,您可以在其中输入自己的多边形,然后进行所需的操作。
我们举个例子:
[[7,86,196,24,199,177,47,169,51,21,224,102,223,146,7,140,7,86]]
如果您在演示中输入这些点(作为主题或剪辑),您将获得以下多边形:
然后进行简化操作,产生以下解决方案:
如果单击“多边形资源管理器”中的“解决方案”,则可以看到简化多边形的坐标: [[199,177,47,169,47.75,141.13,7,140,7,86,49.62,72.02,51,21,114.51,50.73,196,24,197.28,89.49,224,102,223,146,198.38,145.32]]
最后,我将完整的功能代码放在JSBIN中,其中包含SVG绘图函数,因此相当长:
<html>
<head>
<title>Javascript Clipper Library / Simplifying Polygons</title>
<script src="clipper.js"></script>
<script>
function draw() {
var subj_polygons = [[{"X":7,"Y":86},{"X":196,"Y":24},{"X":199,"Y":177},{"X":47,"Y":169},{"X":51,"Y":21},{"X":224,"Y":102},{"X":223,"Y":146},{"X":7,"Y":140},{"X":7,"Y":86}]];
var scale = 100;
subj_polygons = scaleup(subj_polygons, scale);
var cpr = new ClipperLib.Clipper();
cpr.AddPolygons(subj_polygons, ClipperLib.PolyType.ptSubject);
var solution_polygons = new ClipperLib.Polygons();
solution_polygons = cpr.SimplifyPolygons(subj_polygons, ClipperLib.PolyFillType.pftNonZero);
//console.log(JSON.stringify(solution_polygons));
var svg = '<svg style="margin-top:10px; margin-right:10px;margin-bottom:10px;background-color:#dddddd" width="240" height="200">';
svg += '<path stroke="black" fill="yellow" stroke-width="2" d="' + polys2path(solution_polygons, scale) + '"/>';
svg += '</svg>';
document.getElementById('svgcontainer').innerHTML = svg;
}
// helper function to scale up polygon coordinates
function scaleup(poly, scale) {
var i, j;
if (!scale) scale = 1;
for(i = 0; i < poly.length; i++) {
for(j = 0; j < poly[i].length; j++) {
poly[i][j].X *= scale;
poly[i][j].Y *= scale;
}
}
return poly;
}
// converts polygons to SVG path string
function polys2path (poly, scale) {
var path = "", i, j;
if (!scale) scale = 1;
for(i = 0; i < poly.length; i++) {
for(j = 0; j < poly[i].length; j++) {
if (!j) path += "M";
else path += "L";
path += (poly[i][j].X / scale) + ", " + (poly[i][j].Y / scale);
}
path += "Z";
}
return path;
}
</script>
</head>
<body onload="draw()">
<h2>Javascript Clipper Library / Simplifying Polygons</h2>
This page shows an example of simplifying polygon and drawing it using SVG.
<div id="svgcontainer"></div>
</body>
</html>
答案 4 :(得分:0)
您似乎想要查看Convex Hull algorithms。这是几个Convex Hull算法的applet。您可能可以修改其中一种算法以获得极限点并从那里开始。
答案 5 :(得分:0)
好吧,我似乎已经找到了可行的解决方案:
http://mrpyo.github.com/Polygon/
这是ActionScript所以你应该没有问题将它翻译成JavaScript。 如果有人感兴趣,我可以解释使用过的算法......