Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 对X和Y垂直点数组进行排序?监督厅/目标C_Ios_Objective C_Arrays_Sorting_Vertices - Fatal编程技术网

Ios 对X和Y垂直点数组进行排序?监督厅/目标C

Ios 对X和Y垂直点数组进行排序?监督厅/目标C,ios,objective-c,arrays,sorting,vertices,Ios,Objective C,Arrays,Sorting,Vertices,我有一个名为Line的核心数据实体。每行包含一个垂直点的实例,垂直点包含一个x和y属性。这些x和y顶点形成简单的二维多边形 我要做的是对这些线对象的数组进行排序,它是以随机顺序排列的,这样形状的原点,左下角的点,总是数组中的第一个元素,然后是从原点逆时针方向缠绕的剩余顶点 假设我的原始数组中的点是(x-y轴以0,0为中心): 我想这样对它们进行分类: x = 10, y=10 x = 15, y = 10 x = 20 , y= 10 x = 20, y = 20 x = 10, y =20

我有一个名为Line的核心数据实体。每行包含一个垂直点的实例,垂直点包含一个x和y属性。这些x和y顶点形成简单的二维多边形

我要做的是对这些线对象的数组进行排序,它是以随机顺序排列的,这样形状的原点,左下角的点,总是数组中的第一个元素,然后是从原点逆时针方向缠绕的剩余顶点

假设我的原始数组中的点是(x-y轴以0,0为中心):

我想这样对它们进行分类:

x = 10, y=10
x = 15, y = 10
x = 20 , y= 10
x = 20, y = 20
x = 10, y =20

非常感谢

您应该为进行比较的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;
}
希望这有帮助

//延伸

如果不想创建NSManagedObject的子类,可以使用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];
//延伸

或者最简单的解决办法是

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;
}
NSArray*returnedVertices=[verticesPassed SortedArray使用比较器:^(id obj1,id obj2){
//投射到您的对象:
垂直点*p1=(垂直点*)obj1;
垂直点*p2=(垂直点*)obj2;
如果(p1.x>p2.x)
回报率下降;
else if(p1.xp2.y)
回报率下降;
else if(p1.y
])

您可以使用

- (NSArray *)sortedArrayUsingDescriptors:(NSArray *)sortDescriptors
当然可以


您可以使用多个描述符。只需初始化两个描述符,一个用x,一个用y属性。

这里有一个精确规范的建议:

  • 假设第一象限坐标系(y轴朝上)
  • 查找所有点的轴对齐边界框的中心
  • 按向量从中心到点的角度对点进行排序。计算角度,考虑一个指向西南方向的矢量,以逆时针方向上升的角度为0°。
  • 这里有一个解决方案:

    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);
    

    什么是self.x和self.y?我假设您的VerticePoint类包含属性float x;和属性浮动y;。将此方法添加到要排序的类中,即VerticePoint,对吗?这是排序时要使用的条件。否-数组包含顶点点核心数据对象,但代码不在此类中。您可以为顶点点创建NSManagedObject的子类,并将此方法添加到其中。通过在包含顶点的数组上调用sortedArrayUsingSelector:,它应该可以工作。@Ohnomycoco请参阅编辑的文章。这对核心数据对象如何工作?我的VerticePoint是Line对象的子实体。谢谢-这就是我最后要做的。现在还不清楚如何对顶点进行排序:“围绕原点逆时针”听起来像是顶点应该围绕(0,0)大致循环排列,但您的示例显示它们围绕中心排列(15,15)。您应该更准确地描述排序应该如何工作。从原点开始,而不是从周围开始。那不是我写的,“起源”是什么意思?原点上总是有点吗?或者我们应该从离原点最近的点开始?逆时针绕哪个点?如果你仔细阅读,我说过原点总是左下角的点。
    - (NSArray *)sortedArrayUsingDescriptors:(NSArray *)sortDescriptors
    
    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);