这意味着排除任何interiorPolygons
的区域。
一旦具有外points
多边形的质心,一个(即,以Objective-C示例的形式)如何通过减法interiorPolygons
调整质心?或者是否有更优雅的方式一次性计算质心?
如果您帮助使代码正常工作,它将是开源的(WIP here)。
可能会有所帮助:
答案 0 :(得分:1)
今天想一想,将每个内部质心 按区域加权 添加到外部质心会产生合理的意义。 (左侧有一个内部多边形(孔)的正方形会使质心向右移动,与孔的面积成正比。)
不按比例缩放:
- (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;
}
答案 1 :(得分:0)
在Swift 5中
private func centroidForCoordinates(_ coords: [CLLocationCoordinate2D]) -> CLLocationCoordinate2D? {
guard let firstCoordinate = coordinates.first else {
return nil
}
guard coords.count > 1 else {
return firstCoordinate
}
var minX = firstCoordinate.longitude
var maxX = firstCoordinate.longitude
var minY = firstCoordinate.latitude
var maxY = firstCoordinate.latitude
for i in 1..<coords.count {
let current = coords[i]
if minX > current.longitude {
minX = current.longitude
} else if maxX < current.longitude {
maxX = current.longitude
} else if minY > current.latitude {
minY = current.latitude
} else if maxY < current.latitude {
maxY = current.latitude
}
}
let centerX = minX + ((maxX - minX) / 2)
let centerY = minY + ((maxY - minY) / 2)
return CLLocationCoordinate2D(latitude: centerY, longitude: centerX)
}