如何在 JavaScript 中找到凹不规则多边形的质心?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9692448/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can you find the centroid of a concave irregular polygon in JavaScript?
提问by iambriansreed
How can you find the centroid of a concave irregular polygon given its vertices in JavaScript?
在 JavaScript 中,给定顶点,如何找到凹不规则多边形的质心?
I want to pass a set of x,y points to a JavaScript function and be given an x,y point.
我想将一组 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);
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.
该my_points
变量仅表示要给出的点数的格式,而不表示要给出的点数的具体数量。
The centroidreturned 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.
最终目标是在 Google Maps V3 应用程序中的多边形质心处添加标记。
回答by Myobis
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.
对于 2D 表面的质心(这很可能是您需要的),最好从一点数学开始。
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 };
}
回答by pragmar
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 }
回答by Peter Olson
This is fairly simple to do. The centroid of a finite set of kpointsx1, x2, ... xkis described by the formula
这很容易做到。有限集k点x 1, x 2, ... x k的质心由以下公式描述
(x1+ x2+ ... + xk) / k
(x 1+ x 2+ ... + x k) / 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;
}
回答by Abhranil Das
If you are not casual about the definition of 'centroid', thisis 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).
如果您对“质心”的定义不随意,这就是多边形质心的公式。如您所见,它比一组点的质心复杂得多。如果您可以使用点的质心,那很好,但是如果您想要多边形的质心,则必须实现这个公式,顺便说一句,这不是很困难。请记住,在不规则多边形的一般情况下,即您的情况,这两个质心将不同(否则此公式将不存在)。