Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/407.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 从点创建多边形的算法_Javascript_Algorithm_Geometry - Fatal编程技术网

Javascript 从点创建多边形的算法

Javascript 从点创建多边形的算法,javascript,algorithm,geometry,Javascript,Algorithm,Geometry,我想找到一种从随机点创建多边形的好方法 所有的点都应该在多边形中使用,因此每个点都有两个由两条边连接的邻居。任何一条边都不应与另一条交叉 以下是一个可接受结果的示例: 以下是一个不可接受的示例,因为存在相互交叉的边: 这有算法吗?您可以: 确定一些好的开始点,而不是必要的给定点之一。使用一些启发式方法。例如,给定点的“重心”可能是一个有用的选择。但是,在凸包内选择任何一个点都将生成一个多边形,该多边形将具有非相交边。根据选择,多边形可能会更“平滑” 将给定点的坐标转换为极坐标,其中第一步中选

我想找到一种从随机点创建多边形的好方法

所有的点都应该在多边形中使用,因此每个点都有两个由两条边连接的邻居。任何一条边都不应与另一条交叉

以下是一个可接受结果的示例:

以下是一个不可接受的示例,因为存在相互交叉的边:

这有算法吗?

您可以:

  • 确定一些好的开始点,而不是必要的给定点之一。使用一些启发式方法。例如,给定点的“重心”可能是一个有用的选择。但是,在凸包内选择任何一个点都将生成一个多边形,该多边形将具有非相交边。根据选择,多边形可能会更“平滑”

  • 将给定点的坐标转换为极坐标,其中第一步中选择的点为原点(0,0)

  • 按极坐标对点进行排序:首先按极角排序,然后按半径排序(或者使用平方根函数忽略半径的平方)

  • 使用此顺序绘制多边形

  • 以下是交互式代码段中的一个实现:

    函数平方极(点、中心){
    返回[
    数学atan2(点[1]-中心[1],点[0]-中心[0]),
    (点[0]-中心[0])**2+(点[1]-中心[1])**2//距离的平方
    ];
    }
    //主要算法:
    函数多边形排序(点){
    //获取“重心”
    设中心=[点数减少((总和,p)=>sum+p[0],0)/points.length,
    点数减少((总和,p)=>sum+p[1],0)/points.length];
    //按极角和距离排序,以质量中心为中心。
    对于(让点的点)点。推(…平方极(点,中心));
    点排序((a,b)=>a[2]-b[2]| | a[3]-b[3]);
    //扔掉临时极坐标
    对于(点中的点)点,长度-=2;
    }
    设点=[];
    //I/O管理
    让canvas=document.querySelector(“canvas”);
    设ctx=canvas.getContext(“2d”);
    功能图(点){
    clearRect(0,0,canvas.width,canvas.height);
    如果(!points.length)返回;
    for(设[x,y]个点){
    ctx.beginPath();
    弧(x,y,3,0,2*Math.PI,真);
    ctx.fill();
    }
    ctx.beginPath();
    ctx.moveTo(…点[0]);
    对于点切片(1)的(设[x,y])ctx.lineTo(x,y);
    ctx.closePath();
    ctx.stroke();
    }
    canvas.onclick=函数(e){
    设x=e.clientX-this.offsetLeft;
    设y=e.clientY-this.offsetTop;
    
    让match=points.findIndex(([x0,y0])=>Math.abs(x0-x)+Math.abs(y0-y)从一个点开始。将该点与另一个点连接起来。重复操作,直到一条线与另一条线交叉。删除当前线,然后尝试另一个点。如果所有剩余点都已取下,则返回一步。这将是O(n!)最坏的情况。你能展示你的一些代码吗?这能回答你的问题吗?那个dupe引用实际上是关于找到凸包的。。。。