Как вы можете найти центроид вогнутого нерегулярного многоугольника в JavaScript?
Как вы можете найти центроид вогнутого нерегулярного многоугольника с учетом его вершин в 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.
Ответы
Ответ 1
Для центроида 2D-поверхности (который, вероятно, будет тем, что вам нужно)
Лучше всего начать с немного математики.
Я адаптировал его здесь к вашим собственным обозначениям:
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
Принятый ответ имеет проблему, которая становится заметной, когда область многоугольника становится меньше. В большинстве случаев это не будет видно, но может привести к некоторым странным результатам при очень малых размерах. Здесь обновляется это решение для учета этой проблемы.
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 }
Ответ 3
Это довольно просто сделать. центроид конечного набора k точек 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;
}
Ответ 4
Если вы не случайно относитесь к определению "centroid", this > является формулой для центроида многоугольника. Как вы можете видеть, это достаточно сложнее, чем центр тяжести набора точек. Если вы можете сделать с центроидом точек, это прекрасно, но если вы хотите центроид многоугольника, вам придется реализовать эту формулу, что не очень сложно. Помните, что в общем случае нерегулярного многоугольника, в вашем случае, эти две центроиды будут отличаться (иначе эта формула не существовала бы).