我正在使用一个库(JavaScript-Voronoi),它生成代表封闭多边形的线段数组。这些线段是无序的,既包括线段出现的顺序,也包括每个端点的顺序。
注意第一个线段与最后一个(它们共享一个公共点)和倒数第二个的链接。保证每个线段都与另一个线段共享一个端点。
我想将此转换为点列表,以生成适当的SVG多边形:
无论点是顺时针还是逆时针排序都没有关系。 以下是我想出来的代码,但在最坏的情况下,它将需要n^2+n个点比较。是否有更有效的算法来连接所有这些点?
(编辑:如下评论所述,我错了:库中的线段是有序的。然而,问题仍然按照原文提出:假设线段没有任何顺序,因为这样更具有普遍意义。)
例如:
var p1 = {x:13.6,y:13.1}, p2 = {x:37.2,y:35.8}, p3 = {x:99.9,y:14.6},
p4 = {x:99.9,y:45.5}, p5 = {x:33.7,y:66.7};
var segments = [
{ va:p1, vb:p2 },
{ va:p3, vb:p4 },
{ va:p5, vb:p4 },
{ va:p3, vb:p2 },
{ va:p1, vb:p5 } ];
注意第一个线段与最后一个(它们共享一个公共点)和倒数第二个的链接。保证每个线段都与另一个线段共享一个端点。
我想将此转换为点列表,以生成适当的SVG多边形:
console.log( orderedPoints(segments) );
// [
// {"x":33.7,"y":66.7},
// {"x":13.6,"y":13.1},
// {"x":37.2,"y":35.8},
// {"x":99.9,"y":14.6},
// {"x":99.9,"y":45.5}
// ]
无论点是顺时针还是逆时针排序都没有关系。 以下是我想出来的代码,但在最坏的情况下,它将需要n^2+n个点比较。是否有更有效的算法来连接所有这些点?
function orderedPoints(segs){
segs = segs.concat(); // make a mutable copy
var seg = segs.pop(), pts = [seg.va], link = seg.vb;
for (var ct=segs.length;ct--;){
for (var i=segs.length;i--;){
if (segs[i].va==link){
seg = segs.splice(i,1)[0]; pts.push(seg.va); link = seg.vb;
break;
}else if (segs[i].vb==link){
seg = segs.splice(i,1)[0]; pts.push(seg.vb); link = seg.va;
break;
}
}
}
return pts;
}
cell.halfedges.map(function(he){ return he.getStartpoint() })
;尽管我之前所说的,这些边缘实际上已经按逆时针顺序排序了。 - Phrogz