Javascript 求两个六边形之间的距离

Javascript 求两个六边形之间的距离,javascript,geometry,Javascript,Geometry,我有两个六边形,当边缘达到一定的公差时,我试图使它们咬合在一起 如何找到最接近的边 下面是返回两个最近六边形的代码: Canvas.getClosestPiece = function(){ var current = {}; current.x = selection.MidPoint.X; current.y = selection.MidPoint.Y; smallestDistance = null; closestHex = null; hexagons.

我有两个六边形,当边缘达到一定的公差时,我试图使它们咬合在一起

如何找到最接近的边

下面是返回两个最近六边形的代码:

Canvas.getClosestPiece = function(){
  var current = {};
  current.x = selection.MidPoint.X;
  current.y = selection.MidPoint.Y;
  smallestDistance = null;
  closestHex = null;

  hexagons.forEach(function(hexagon){
    if(hexagon !== selection){
      testPiece = {};
      testPiece.x = hexagon.MidPoint.X;
      testPiece.y = hexagon.MidPoint.Y;
      if((lineDistance(current, testPiece) < smallestDistance) || smallestDistance === null){
        smallestDistance = lineDistance(current, testPiece)
        closestHex = hexagon
        hexagons.forEach(function(hexagon){
          hexagon.lineColor = 'grey'
        })
        hexagon.lineColor = 'red';
      }
    }
  })
  // console.log(smallestDistance)
  return [selection, closestHex]
}
下面是GetClosestPice返回的一个六边形的标准点阵列:

Point {X: 658, Y: 284} 
Point {X: 704, Y: 304} 
Point {X: 704, Y: 354} 
Point {X: 658, Y: 375} 
Point {X: 613, Y: 354} 
Point {X: 613, Y: 304} 

如果有两个点的坐标像p1(x1,y1)和p2(x2,y2)。您可以这样做:

var disptance = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
有关是否要捕捉的计算,请参见其他答案

至于在哪里捕捉(哪些边),我认为这是你真正的问题:使用

(midy1-midy2,midx1-midx2)

您将获得一个弧度值,该值描述六边形之间连接线的角度。0=水平线

计算数学地板(值*6/(2*pi))-->得到一个介于0到5之间的数字,表示边配对

如果您的六边形是可旋转的,则需要在
中添加/减去旋转素(以rad为单位)。(最好在一张纸上标出这些标志)


编辑:关于距离计算,建议尽可能长地使用距离的平方(例如,将x^2+y^2与阈值^2进行比较),以避免昂贵的Math.sqrt操作。尤其是在测试大量其他物体的距离时。

使用欧几里安距离公式


dist=sqrt((x2 xq)^2+(y2-y1)^2)

要找到最接近的边,您必须告诉我们如何获得每个六边形的边线信息。这里,我假设它们可以作为每个六边形的属性通过数组访问。每个六边形有6条边(边[0]到边[5])。我们可以通过循环并测量每两条边的中心之间的距离来找到最近的边。示例代码如下所示:

var dMin=-1, iMin=-1, jMin=-1; //info about the min distance

for(var i=0; i<5; i++) //loop through hexagon1.edges
{
 var p1 = midPointOfLine( hexagon1.edges[i] ); //center of this edge line 
 for(var j=0; j<5; j++) //loop through hexagon2.edges
  {
    var p2 = midPointOfLine( hexagon2.edges[j] ); //center of this edge line 
    var d = getDistance(p1, p2); //get distance of two points
    if (d<dMin || dMin==-1) {dMin=d; iMin=i; jMin=j;} //store the info about the min distance
  }
}


 function midPointOfLine(edge) // return new point( X=(X1+X2)/2 , Y=(Y1+Y2)/2 )
 {
  var mp; //define a new point
  mp.X = (edge.startPoint.X + edge.endPoint.X) / 2;
  mp.Y = (edge.startPoint.Y + edge.endPoint.Y) / 2;
  return mp;
 }

 function getDistance(p1, p2) //return sqrt( (X2-X1)^2 + (Y2-Y1)^2 )
 {
  return Math.sqrt( Math.pow(p2.X - p1.X, 2) + Math.pow(p2.Y - p1.Y, 2) );
 }
vardmin=-1,iMin=-1,jMin=-1//关于最小距离的信息

对于(var i=0;这听起来更像是一个数学问题,而不是一个编程问题。不管怎样,到目前为止你做了什么?你需要显示代码以获得帮助。这是一个数学问题,我有一堆代码与处理两点之间的拖动和距离的问题无关。你希望看到什么?如果不需要100%的精确结果,哟u可以计算六边形中心之间的距离,从而将它们近似为圆。一旦(x1-x2)^2+(y1-y2)^2低于阈值,让它们捕捉。六边形应该是可旋转的,还是始终具有相同的方向并只是四处移动?您想知道哪条边吗(右、左、右上、左上、左下、右下)或者哪一个六边形是最接近的?谢谢这确实有帮助,那么这就是我的黑线的视觉表现吗?关于-如果-捕捉,我仍在试图找出如何应用欧几里安距离公式。在西南边缘完美捕捉会使我的中点到中点的距离为85,而在西部完美捕捉edge给了我93。是否有一个公式来测试到相应边之间的距离?(NE和SW)vs(N和S)?为了获得更好的性能,正如Torben Klein所说,当测试距离值时,您可以使用ommit
sqrt
函数,因为如果a大于b,那么aa也将大于bb,sqrt(a)也将大于sqrt(b)。
var dMin=-1, iMin=-1, jMin=-1; //info about the min distance

for(var i=0; i<5; i++) //loop through hexagon1.edges
{
 var p1 = midPointOfLine( hexagon1.edges[i] ); //center of this edge line 
 for(var j=0; j<5; j++) //loop through hexagon2.edges
  {
    var p2 = midPointOfLine( hexagon2.edges[j] ); //center of this edge line 
    var d = getDistance(p1, p2); //get distance of two points
    if (d<dMin || dMin==-1) {dMin=d; iMin=i; jMin=j;} //store the info about the min distance
  }
}


 function midPointOfLine(edge) // return new point( X=(X1+X2)/2 , Y=(Y1+Y2)/2 )
 {
  var mp; //define a new point
  mp.X = (edge.startPoint.X + edge.endPoint.X) / 2;
  mp.Y = (edge.startPoint.Y + edge.endPoint.Y) / 2;
  return mp;
 }

 function getDistance(p1, p2) //return sqrt( (X2-X1)^2 + (Y2-Y1)^2 )
 {
  return Math.sqrt( Math.pow(p2.X - p1.X, 2) + Math.pow(p2.Y - p1.Y, 2) );
 }