Думая об этом сегодня, это делает качественный смысл, что добавление каждого внутренний центроида взвешенный по площади к внешней центроиде придет к чему-то разумному. (Квадрат с внутренним многоугольником (отверстие) на левой стороне будет сместить центр тяжести вправо, прямо пропорционально площади отверстия.)
Не в масштабе:
- (MKMapPoint)calculateCentroid
{
switch (self.pointCount) {
case 0: return MKMapPointMake(0.0,
0.0);
case 1: return MKMapPointMake(self.points[0].x,
self.points[0].y);
case 2: return MKMapPointMake((self.points[0].x + self.points[1].x)/2.0,
(self.points[0].y + self.points[1].y)/2.0);
}
// onward implies pointCount >= 3
MKMapPoint centroid;
MKMapPoint *previousPoint = &(self.points[self.pointCount-1]); // for i=0, wrap around to the last point
for (NSUInteger i = 0; i < self.pointCount; ++i) {
MKMapPoint *point = &(self.points[i]);
double delta = (previousPoint->x * point->y) - (point->x * previousPoint->y); // x[i-1]*y[i] + x[i]*y[i-1]
centroid.x += (previousPoint->x + point->x) * delta; // (x[i-1] + x[i])/delta
centroid.y += (previousPoint->y + point->y) * delta; // (y[i-1] + y[i])/delta
previousPoint = point;
}
centroid.x /= 6.0 * self.area;
centroid.y /= 6.0 * self.area;
// interiorPolygons are holes (subtractive geometry model)
for (MKPolygon *interiorPoly in self.interiorPolygons) {
if (interiorPoly.area == 0.0) {
continue; // avoid div-by-zero
}
centroid.x += interiorPoly.centroid.x/interiorPoly.area;
centroid.y += interiorPoly.centroid.y/interiorPoly.area;
}
return centroid;
}
Обновлено избежать ручной размахивая ответами. – Barry
Связанные, но разные вопросы и ответы https://stackoverflow.com/questions/19766485/how-to-calculate-centroid-of-polygon-in-c – Barry