如何在JavaScript中找到凹面不规则多边形的质心?

如何在JavaScript中找到凹面不规则多边形的质心?,javascript,polygon,Javascript,Polygon,在JavaScript中,如何在给定顶点的情况下找到凹形不规则多边形的质心 我想将一组x,y点传递给一个JavaScript函数,并得到一个x,y点 var my_points = [{x:3,y:1},{x:5,y:8},{x:2,y:9}]; function get_polygon_centroid(points){ // answer } var my_centroid = get_polygon_centroid(my_points); my_points变量只表示要给出

在JavaScript中,如何在给定顶点的情况下找到凹形不规则多边形的质心

我想将一组x,y点传递给一个JavaScript函数,并得到一个x,y点

var my_points = [{x:3,y:1},{x:5,y:8},{x:2,y:9}];

function get_polygon_centroid(points){
    // answer
}

var my_centroid = get_polygon_centroid(my_points);
my_points
变量只表示要给出的点的格式,不表示要给出的点的具体计数

返回的质心将是多边形内的某个点


最终目标是在Google Maps V3应用程序中的多边形质心处添加一个标记。

这相当简单。x1,x2。。。xk由公式描述

(x1+x2+…+xk)/k

这意味着我们可以把所有的点加起来,然后除以点数,如下所示:

function getPolygonCentroid(points){ 
  var centroid = {x: 0, y: 0};
  for(var i = 0; i < points.length; i++) {
     var point = points[i];
     centroid.x += point.x;
     centroid.y += point.y;
  }
  centroid.x /= points.length;
  centroid.y /= points.length;
  return centroid;
} 
函数getPolygonCentroid(点){ var形心={x:0,y:0}; 对于(变量i=0;i用于二维曲面的质心(这可能是您需要的), 最好是从一开始

我在这里将其改编为您自己的符号:

函数获取多边形质心(pts){
var first=pts[0],last=pts[pts.length-1];
如果(first.x!=last.x | | first.y!=last.y)点推(first);
var twicearea=0,
x=0,y=0,
nPts=分时长度,
p1,p2,f;

对于(var i=0,j=nPts-1;i如果你对“质心”的定义不太在意,这是多边形质心的公式。正如你所看到的,它比一组点的质心要复杂得多。如果你能处理点的质心,那很好,但如果你想要多边形的质心,你必须实现它这个公式,顺便说一句,不是很难。请记住,在不规则多边形的一般情况下,这两个质心是不同的(否则这个公式就不存在了).

公认的答案有一个问题,随着多边形的面积变小,这个问题会变得突出。在大多数情况下,它不可见,但会在非常小的维度上导致一些奇怪的结果。下面是解决此问题的解决方案的更新

function get_polygon_centroid(pts) {
   var first = pts[0], last = pts[pts.length-1];
   if (first.x != last.x || first.y != last.y) pts.push(first);
   var twicearea=0,
   x=0, y=0,
   nPts = pts.length,
   p1, p2, f;
   for ( var i=0, j=nPts-1 ; i<nPts ; j=i++ ) {
      p1 = pts[i]; p2 = pts[j];
      f = (p1.y - first.y) * (p2.x - first.x) - (p2.y - first.y) * (p1.x - first.x);
      twicearea += f;
      x += (p1.x + p2.x - 2 * first.x) * f;
      y += (p1.y + p2.y - 2 * first.y) * f;
   }
   f = twicearea * 3;
   return { x:x/f + first.x, y:y/f + first.y };
}

这篇文章有javascript代码:你有没有考虑过
google.maps.LatLngBounds.getCenter()
?我发现了这个代码:@AlexKorban center!=centroid-“凹形不规则多边形”正如Zevan所建议的,在上有一个JavaScript质心函数。不完全确定它是否会处理凸多边形,但随附的插图表明它会处理凸多边形。-1:在同一wiki页面中给出的多边形质心与形成它的点的质心不同。您对多个点的质心的定义如下:正确。但是任何区域的质心都被定义为其质心的位置,通常与顶点的质心不同。我试图纠正其中一个“点”中缺少的“I”引用,但愚蠢的编辑器要求我至少更改6个字符,因此我将示例中的方法名称更改为camelcased(这在JS中更常见)-希望这没问题Peter Olson?(我不知道如何进行更改,这样示例就不会因拼写错误而引发错误)您给定的质心仍然是一组点的质心;这组点只是无限的…:)当然,我只是不想对它做太多的阐述。在另一种情况下,我们认为点是质量相等的质量点,在这里我们考虑质量在多边形中均匀分布。正如维基百科在引用的文章中所说的,重要的是要注意:“假设顶点按照它们在多边形周长上出现的顺序进行编号,并且假设顶点(xn,yn)与(x0,y0)相同”如果(x0,y0)!=(xn,yn)我认为在第一行
var first=t[0]
它的意思是
var first=pts[0]
感谢您发现了这个@joerocc。这个方法显示了与Google Maps(bounds.getCenter)和MySQL(Centroid function)…+1不同的结果,用于处理基本方法的实际问题,令人惊讶的是,在维基百科和我检查过的其他地方没有提到。但是,解决方案中有一个错误:以
x+=(p1.y+p2.y…
y+=(p1.x+p2.x…
当然应该是
x+=(p1.x+p2.x…
y+=(p1.y+p2.y…
.Yikes)!谢谢你抓到了,乔纳斯。修好了。
var points = [
    {x:78.0001462, y: 40.0008827},
    {x:78.0000228, y: 40.0008940},
    {x:78.0000242, y: 40.0009264},
    {x:78.0001462, y: 40.0008827},
];
// original get_polygon_centroid(points)
// results in { x: 77.99957948181007, y: 40.00065236005001 }
console.log(get_polygon_centroid(points))
// result is { x: 78.0000644, y: 40.000901033333335 }