Javascript 数学-获取图表起点周围线条闭合的最小多边形

Javascript 数学-获取图表起点周围线条闭合的最小多边形,javascript,math,charts,Javascript,Math,Charts,我试图得到最小多边形的点,这些线围绕图表的起点创建,也就是最里面的多边形。根据某些可以更改的参数,这些线会有所不同 此类图表的示例: 从图表中可以看到,这些线相交多次,从而创建多个多边形。但是,我只想得到图表起点(中心)内的最小多边形 我在考虑用x轴从y轴到左和右从顶部和底部绘制多条平行线(在+y轴和-y轴上的最小截距),并查看哪条线首先被“击中”,以获得包围该多边形的线,然后获得它们的顶点交点,这些顶点可用于绘制多边形。但是,由于要精确地检查这些线需要很多点,我想知道是否有更优雅的解决方案?

我试图得到最小多边形的点,这些线围绕图表的起点创建,也就是最里面的多边形。根据某些可以更改的参数,这些线会有所不同

此类图表的示例:

从图表中可以看到,这些线相交多次,从而创建多个多边形。但是,我只想得到图表起点(中心)内的最小多边形


我在考虑用x轴从y轴到左和右从顶部和底部绘制多条平行线(在+y轴和-y轴上的最小截距),并查看哪条线首先被“击中”,以获得包围该多边形的线,然后获得它们的顶点交点,这些顶点可用于绘制多边形。但是,由于要精确地检查这些线需要很多点,我想知道是否有更优雅的解决方案?

这里有一个可能的算法:

  • 当未找到循环时:
    • 从某一点开始(x,y)在某一行上
      L
    • 沿顺时针方向在
      L
      上找到下一个交点
      (x',y')
    • 如果原点
      (0,0)
      位于此行的右侧:
      • x=x'
      • y=y'
      • L=
        那条新行
  • 如果找到循环:此循环就是多边形

以下是一种可能的算法:

  • 当未找到循环时:
    • 从某一点开始(x,y)在某一行上
      L
    • 沿顺时针方向在
      L
      上找到下一个交点
      (x',y')
    • 如果原点
      (0,0)
      位于此行的右侧:
      • x=x'
      • y=y'
      • L=
        那条新行
  • 如果找到循环:此循环就是多边形

在Stef和他的算法的帮助下,我设法解决了这个问题。以下是我使用的代码:

const getcrossions=async(
行:IPoint[][]
):承诺=>{
让线相交:i相交线[]=[];
行。forEach((行)=>{
让线相交:I相交线={
行:行,,
交叉点:[],
};
设x1=线[1].x;
设y1=线[1].y;
设x2=线[2].x;
设y2=线[2].y;
for(设i=0;i1 | | ub<0 | | ub>1)继续;
设x=x1+ua*(x2-x1);
设y=y1+ua*(y2-y1);
lineIntersect.intersects.push({
x:+x.toFixed(4),
y:+y.toFixed(4),
});
}
lineIntersect.intersects.sort((a,b)=>{
返回a.x-b.x;
});
直线相交。推动(直线相交);
});
返回线相交;
};
常量getStartingPoint=async(相交:IPoint[])=>{
let结果:i点=相交[0];
让距离=result.x*result.x+result.y*result.y;
相交。forEach((i)=>{
设newDistance=i.x*i.x+i.y*i.y;
如果(新距离<距离){
距离=新距离;
结果=i;
}
});
返回结果;
};
常量calcPolygonArea=async(多边形:IPoint[])=>{
设total=0;
for(设i=0,l=polygon.length;i{
let结果:IPoint[]=[];
让交叉点=等待获取交叉点(线);
让intersectionVertices=crossions.map((x)=>x.intersects.flat();
让startingPoint=等待getStartingPoint(相交顶点);
设交叉线=交叉点。过滤器((x)=>
x、 交叉(
(p) =>p.x===startingPoint.x&&p.y===startingPoint.y
)
);
让newPoints:IPoint[]=[];
常数x0=0;
常数y0=0;
交叉线。forEach((线)=>{
设x1=起始点x;
设y1=起始点y;
设pointIndex=line.intersects.findIndex(
(p) =>p.x===startingPoint.x&&p.y===startingPoint.y
);
让d;
if(直线与[pointIndex-1]相交){
设x2=直线。与[pointIndex-1].x相交;
设y2=line.intersects[pointIndex-1].y;
d=(x0-x1)*(y2-y1)-(y0-y1)*(x2-x1);
如果(d>0)newPoints.push({x:x2,y:y2});
}
if(直线与[pointIndex+1]相交){
设x2=直线。与[pointIndex+1]相交。x;
设y2=直线。与[pointIndex+1]相交。y;
d=(x0-x1)*(y2-y1)-(y0-y1)*(x2-x1);
如果(d>0)newPoints.push({x:x2,y:y2});
}
});
let result1:IPoint[]=[];
let result2:IPoint[]=[];
for(设i=0;i