How can you find the centroid of a concave irregular polygon in JavaScript?

早过忘川 提交于 2019-11-27 21:01:23

问题


How can you find the centroid of a concave irregular polygon given its vertices in JavaScript?

I want to pass a set of x,y points to a JavaScript function and be given an x,y point.

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);

The my_points variable is only supposed to represent the format of the points to be given, not to represent the specific count of points to be given.

The centroid returned will be a point somewhere inside the polygon.

The end goal would be to add a marker at the centroid of a polygon in a Google Maps V3 application.


回答1:


For the centroid of the 2D surface (which is likely to be what you need), The best is to start with a little bit of maths.

I adapted it here to your own notation :

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.x*p2.y - p2.x*p1.y;
      twicearea += f;          
      x += ( p1.x + p2.x ) * f;
      y += ( p1.y + p2.y ) * f;
   }
   f = twicearea * 3;
   return { x:x/f, y:y/f };
}



回答2:


The accepted answer has an issue which becomes prominent as the polygon's area becomes smaller. It would not be visible in most cases, but can result in some weird results at very small dimensions. Here's an update to that solution to account for this issue.

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 };
}

Here's a case of a centroid ending up outside of a small polygon for anyone curious as to what I'm talking about:

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 }



回答3:


This is fairly simple to do. The centroid of a finite set of k points x1, x2, ... xk is described by the formula

(x1 + x2 + ... + xk) / k

That means we can just add all the points up and then divide by the number of points, like this:

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;
} 



回答4:


If you are not casual about the definition of 'centroid', this is the formula for the centroid of a polygon. As you can see, it's sufficiently more complicated than the centroid of a set of points. If you can do with the centroid of the points, that's fine, but if you want the centroid of the polygon, you'd have to implement this formula, which btw is not very difficult. Please remember that in the general case of an irregular polygon, which is your case, these two centroids will be different (otherwise this formula wouldn't exist).



来源:https://stackoverflow.com/questions/9692448/how-can-you-find-the-centroid-of-a-concave-irregular-polygon-in-javascript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!