2014-09-10 2 views
1

Это означает исключение площади (областей) любого interiorPolygons.Найти точный центроид (как MKMapPoint) MKPolygon

Как только один имеет центр тяжести внешнего полигона points, как один (т. Е. В виде примера Objective-C) отрегулирует центроид на вычитание interiorPolygons? Или есть более элегантный способ вычислить центроид за один раз?

Если вы хотите, чтобы код работал, он будет открытым исходным кодом (WIP here).

Может быть полезен:

  1. http://www.ecourses.ou.edu/cgi-bin/eBook.cgi?topic=st&chap_sec=07.2&page=case_sol
  2. https://en.wikipedia.org/wiki/Centroid#Centroid_of_polygon
+0

Обновлено избежать ручной размахивая ответами. – Barry

+0

Связанные, но разные вопросы и ответы https://stackoverflow.com/questions/19766485/how-to-calculate-centroid-of-polygon-in-c – Barry

ответ

1

Думая об этом сегодня, это делает качественный смысл, что добавление каждого внутренний центроида взвешенный по площади к внешней центроиде придет к чему-то разумному. (Квадрат с внутренним многоугольником (отверстие) на левой стороне будет сместить центр тяжести вправо, прямо пропорционально площади отверстия.)

Не в масштабе: nothing to scale

- (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; 
} 
Смежные вопросы