如何在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应用程序中的多边形的质心处添加标记。
答案 0 :(得分:26)
对于2D表面的质心(可能是你需要的), 最好的方法是从a little bit of maths开始。
我在这里根据你自己的符号进行了调整:
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 };
}
答案 1 :(得分:5)
随着多边形区域变小,接受的答案有一个问题变得突出。它在大多数情况下都不可见,但可能会在非常小的尺寸上产生一些奇怪的结果。这是解决此问题的解决方案的更新。
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 };
}
这是一个质心的结果,在一个小多边形之外,对于任何对我正在谈论的内容感兴趣的人来说都是:
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 }
答案 2 :(得分:3)
这很简单。公式描述centroid of a finite set of k points x 1 ,x 2 ,... x k
(x 1 + x 2 + ... + x k )/ 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;
}
答案 3 :(得分:1)
如果你对“质心”的定义并不随意,this是多边形质心的公式。如您所见,它比一组点的质心复杂得多。如果你可以处理点的质心,那很好,但是如果你想要多边形的质心,你必须实现这个公式,顺便说一下并不是很困难。请记住,在一般情况下,不规则多边形,这是你的情况,这两个质心将是不同的(否则这个公式将不存在)。