我正在尝试创建一个Javascript Web应用程序,其中用户单击画布以删除无限量的点。有一个解决按钮,当点击时在点之间画线,这样所有的点都被正好2个其他点连接,没有线可以交叉。到目前为止,我的代码中存在某些行仍然交叉的情况,我无法以编程方式找出连接所有点的逻辑,而不会有任何行穿过。
到目前为止,我收集所有点(X-Y坐标)并将它们放在JavaScript对象数组中。然后,我需要对数组进行排序,以便以正确的顺序绘制它。除了订单并不总是满足要求之外,一切都在这一点上起作用。
我的问题:是否有人对一系列规则有任何想法,这些规则会对这些点(X-Y坐标)进行排序,以便它们全部连接但从不交叉,这将适用于每种情况?
感谢您的帮助。
var centroid = get_polygon_centroid($points);
$points = _.sortBy($points, function(p){
var dx = p.coords.x-centroid.x;
var dy = p.coords.y-centroid.y;
return dx*dx + dy*dy;
});
$points = _.sortBy($points, function(p){
var dx = p.coords.x-centroid.x;
var dy = p.coords.y-centroid.y;
return Math.atan2(dy, dx);
});
$points.push($points[0]);
答案 0 :(得分:5)
这是一个算法:
Math.atan2(p.y-c.y, p.x-c.x)
来完成,其中p是当前点,c是中心。这应该会产生一个连通图,其中没有两条线在O(n log n)时间内相交。
<强>更新强>:
此代码应该有效。
//iterate through all points and calculate the center, c
var c = {x:0, y:0}, p;
for (p : points) {
c.x+=p.coords.x;
c.y+=p.coords.y;
}
c.x/=points.length;
c.y/=points.length;
points.sort(function(p1, p2){
var dx1 = p1.coords.x-c.x;
var dy1 = p1.coords.y-c.y;
var a1 = Math.atan2(dy1, dx1);
var dx2 = p2.coords.x-c.x;
var dy2 = p2.coords.y-c.y;
var a2 = Math.atan2(dy2, dx2);
//If angles are the same, sort by length
if (a1===a2){
var d1 = dx1*dx1 + dy1*dy1;
var d2 = dx2*dx2 + dy2*dy2;
return d1-d2;
}
//otherwise sort by angle
return a1-a2;
}
//Iterate through all Points and draw lines between them
var i;
for (i=0;i<n;i++){
//This is not real code \/
line(p[i], p[(i+1)%n]);
}