sortingX和Y的Vertice点的数组? iOS / Objective C
我有一个名为Line的核心数据实体。 每行包含一个包含x和y属性的VerticePoint实例。 这些x和y顶点形成简单的2D多边形。
我想要做的是对这些Line对象的数组进行sorting,这些对象的排列顺序是随机的,这样形状的原点(左下angular的点)始终是数组中的第一个元素,然后是其余的顶点,顺时针方向从原点。
所以说我的原始数组中的点是(xy轴居中在0,0):
x = 20, y = 20 x = 20 , y= 10 x = 10, y=10 x = 10, y =20 x = 15, y = 10
我想像这样sorting他们:
x = 10, y=10 x = 15, y = 10 x = 20 , y= 10 x = 20, y = 20 x = 10, y =20
非常感谢
您可以使用
- (NSArray *)sortedArrayUsingDescriptors:(NSArray *)sortDescriptors
的NSArray。
您可以使用多个描述符。 只需用x来初始化两个描述符,一个使用y属性。
这是一个精确的规格build议:
- 假定第一个象限坐标系(y轴向上)。
- find所有点的轴alignment边界框的中心。
- 按照从中心到点的vector的angular度对点进行sorting。 为了计算angular度,考虑指向西南方向的向量为0°,并且逆时针方向上升。
这里有一个解决scheme:
NSArray *points = @[ [NSValue valueWithCGPoint:(CGPoint){20, 20}], [NSValue valueWithCGPoint:(CGPoint){20, 10}], [NSValue valueWithCGPoint:(CGPoint){10, 10}], [NSValue valueWithCGPoint:(CGPoint){10, 20}], [NSValue valueWithCGPoint:(CGPoint){15, 10}], ]; CGPoint min = [points[0] CGPointValue]; CGPoint max = min; for (NSValue *value in points) { CGPoint point = [value CGPointValue]; min.x = fminf(point.x, min.x); min.y = fminf(point.y, min.y); max.x = fmaxf(point.x, max.x); max.y = fmaxf(point.y, max.y); } CGPoint center = { 0.5f * (min.x + max.x), 0.5f * (min.y + max.y), }; NSLog(@"center: %@", NSStringFromCGPoint(center)); NSNumber *(^angleFromPoint)(id) = ^(NSValue *value){ CGPoint point = [value CGPointValue]; CGFloat theta = atan2f(point.y - center.y, point.x - center.x); CGFloat angle = fmodf(M_PI - M_PI_4 + theta, 2 * M_PI); return @(angle); }; NSArray *sortedPoints = [points sortedArrayUsingComparator:^NSComparisonResult(id a, id b) { return [angleFromPoint(a) compare:angleFromPoint(b)]; }]; NSLog(@"sorted points: %@", sortedPoints);
你应该实现你的VerticePoint对象的方法来做比较,就像这样:
- (NSComparisonResult)compare:(VerticePoint *)vpoint { if (self.x > vpiont.x) return NSOrderedAscending; else if (self.x < vpiont.x) return NSOrderedDescending; else if (self.y > vpiont.y) return NSOrderedAscending; else if (self.y < vpiont.y) return NSOrderedDescending; else return NSOrderedSame; }
之后,如果你有你的VerticePoint对象的数组,你调用:
NSArray *sortedArray = [yourArray sortedArrayUsingSelector:@selector(compare:)];
希望这个帮助。
// EXTENDED
如果你不想创buildNSManagedObject的子类,你可以使用NSSortDescriptor:
NSFetchRequest *request = [[NSFetchRequest alloc] init]; [request setEntity:[NSEntityDescription entityForName:@"ENTITYNAME" inManagedObjectContext:context]]; NSSortDescriptor *sortDescriptorX = [NSSortDescriptor sortDescriptorWithKey:@"yourObjecy.x" ascending:YES]; NSSortDescriptor *sortDescriptorY = [NSSortDescriptor sortDescriptorWithKey:@"yourObjecy.y" ascending:YES]; [request setSortDescriptors:[NSArray arrayWithObjects:sortDescriptorX, sortDescriptorY, nil]]; NSArray *sortedResults = [context executeFetchRequest:request error:nil];
//扩展
或者最简单的解决scheme是
NSArray *returnedVertices = [verticesPassed sortedArrayUsingComparator:^(id obj1, id obj2) { //Cast to your object: VerticePoint *p1 = (VerticePoint*)obj1; VerticePoint *p2 = (VerticePoint*)obj2; if (p1.x > p2.x) return NSOrderedAscending; else if (p1.x < p2.x) return NSOrderedDescending; else if (p1.y > p2.y) return NSOrderedAscending; else if (p1.y < p2.y) return NSOrderedDescending; else return NSOrderedSame; }
]。