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议:

  1. 假定第一个象限坐标系(y轴向上)。
  2. find所有点的轴alignment边界框的中心。
  3. 按照从中心到点的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; } 

]。