Как сформировать массив CGPoint в Objective C - PullRequest
29 голосов
/ 03 июня 2009

Я хочу получить эту структуру

CGPoint addLines1[] =
{
    CGPointMake(30.0, 150.0),
    CGPointMake(41.67, 145.19),
    CGPointMake(53.33, 103.25),
    CGPointMake(65.0, 131.67),
    CGPointMake(76.67, 106.11),
    CGPointMake(88.33, 110.20),
    CGPointMake(100.0, 111.54),
    CGPointMake(111.67, 112.13),
    CGPointMake(123.33, 115.66),
    CGPointMake(135.0, 123.7),
    CGPointMake(146.67, 125.53),
    CGPointMake(158.33, 115.1),
    CGPointMake(170.0, 69.38),
    CGPointMake(181.67, 112.47),
    CGPointMake(193.33, 65.1),
    CGPointMake(205.0, 103.33),
    CGPointMake(216.67, 92.6),
    CGPointMake(228.33, 54.76),
    CGPointMake(240.0, 79.66),
    CGPointMake(251.67, 53.81),
    CGPointMake(263.33, 56.81),
    CGPointMake(275.0, 88.19),
    CGPointMake(286.67, 74.81),
    CGPointMake(298.33, 28.1),
    CGPointMake(310, 20.0),
};

Для того, чтобы сделать некоторые расчеты и нарисовать данные.

у меня CGPoint *lines = appDelegate.averageResponseTimePoints;

Как сделать массив addLines[] из *lines?

Ответы [ 5 ]

51 голосов
/ 21 мая 2012

Для iOS:

Создать массив:

NSArray *myCGPointArray = @[[NSValue valueWithCGPoint:CGPointMake(30.0, 150.0)],[NSValue valueWithCGPoint:CGPointMake(41.67, 145.19)]];

Получить 1-й объект CGPoint:

CGPoint myPoint = [myCGPointArray[0] CGPointValue];
50 голосов
/ 03 июня 2009

Массивы C на самом деле не являются массивами во время выполнения, где они являются просто указателями на непрерывный блок объектов одного типа. Когда вы видите items[n], это просто синтаксический сахар для *(items+n).

В вашем примере addLines[1] будет *(lines+1), а addLines[0] будет *(lines+0), что составляет *lines. Итак, addLines это просто lines без разыменования указателя. *lines - первый элемент в массиве, а lines - весь массив.

Массивы имеют некоторые отличия от указателей во время компиляции. Например, sizeof(addLines) даст вам размер всего массива.

Массив теряется, как только вы передаете массив где-нибудь, где его размер может быть переменным, но вы все равно можете использовать оператор индекса. Например:

#include <Foundation/Foundation.h>

#define showsize( expr ) ( printf(#expr " = %zd\n", ( expr ) ) )

CGPoint *
pass_back(CGPoint points[4])
{
    showsize(sizeof(points));
    return points;
}

int
main(void)
{
    CGPoint square[] = {CGPointMake(-1.0,  1.0),
                        CGPointMake( 1.0,  1.0),
                        CGPointMake( 1.0, -1.0),
                        CGPointMake(-1.0, -1.0)};
    CGPoint* returned;
    int i;

    showsize(sizeof(CGPoint));
    showsize(sizeof(CGPoint*));
    showsize(sizeof(square));
    returned = pass_back(square);
    showsize(sizeof(returned));

    for (i = 0; i < 4; ++i) {
        printf("returned[%d] = {%0.1f, %0.1f}\n", i, (float) returned[i].x,
                                                 (float) returned[i].y);
    }

    return 0;
}

На моем Mac выдается следующее:

sizeof(CGPoint) = 8
sizeof(CGPoint*) = 4
sizeof(square) = 32
sizeof(points) = 4
sizeof(returned) = 4
returned[0] = {-1.0, 1.0}
returned[1] = {1.0, 1.0}
returned[2] = {1.0, -1.0}
returned[3] = {-1.0, -1.0}

Здесь square - это размер четырех CGPoint с, но однажды отправленный в функцию pass_back, это всего лишь размер указателя, потому что это так и есть. Когда указатель возвращается (и называется returned), он все еще может использоваться как массив.

Обратите внимание на магическое число 4 в цикле. Указатель не знает длину массива, на который он указывает.

Массивы нельзя переназначить с помощью оператора =. Если вам действительно нужно заполнить addLines точками из lines, вы можете сделать это следующим образом:

memcpy(addLines, lines, sizeof(CGPoint) * numberOfPoints);

Вам нужно откуда-то взять numberOfPoints, а addLines должно быть достаточно большим, чтобы справиться с этими точками. Это нормально, если число точек является константой, но было бы плохо , если количество точек может изменяться во время выполнения, особенно если точки приходят из внешнего мира (например, выполнение произвольного кода). 1044 *

Я бы изменил averageResponseTimePoints, чтобы он возвращал NSArray, а не массив в стиле C. Вам нужно будет инкапсулировать CGPoint s в объектах - либо ваш собственный объект, либо NSValue s.

Вот пример того, как вы могли бы написать averageResponseTimePoints:

- (NSArray*) averageResponseTimePoints
{
    NSMutableArray* result = [[[NSMutableArray alloc] init] autorelease];

    for (int i = 0; i < numberOfPoints; ++i) {
        NSValue* point = [NSValue value:points+i
                           withObjCType:@encode(CGPoint)];
        [result addObject:point];
    }

    return result;
}

Если ваш код работает с CocoaTouch, вы можете использовать его для создания значения точки:

NSValue* point = [NSValue valueWithCGPoint:points[i]];

Чтобы вывести CGPoint из массива, вы могли бы написать что-то вроде этого:

for (NSValue* value in result) {
    NSPoint pt;
    [value getValue:&pt];
    NSLog(@"%f %f", pt.x, pt.y);
}

Или с CocoaTouch:

CGPoint pt = [value CGPointValue];
4 голосов
/ 04 декабря 2012

Попробуйте это

CGPoint A[10];
A[0] = CGPointMake(10.0, 10.0);
A[1] = CGPointMake(10.0, 12.0);
float x = A[1].y;
NSLog(@"%.0f", x);

Это работает. Удачи.

3 голосов
/ 25 марта 2013

Я попробовал ответ Тибидабо, и он не сработал для меня. Было сказано, что [myCGPointArray objectAtIndex: 0] имеет тип id, поэтому я не могу вызвать CGPointValue для него. гм.

это сработало, однако:

NSArray *points = [NSArray arrayWithObjects:
                   [NSValue valueWithCGPoint:CGPointMake(5.5, 6.6)],
                   [NSValue valueWithCGPoint:CGPointMake(7.7, 8.8)],
                   nil];

NSValue *val = [points objectAtIndex:0];
CGPoint point = [val CGPointValue];
float X = point.x;
NSLog(@"cgpoint value is: %f", X);

или

NSArray *points = [NSArray arrayWithObjects:
                        [NSValue valueWithCGPoint:CGPointMake(20, 6.6)],
                        [NSValue valueWithCGPoint:CGPointMake(7.7, 8.8)],
                        nil];
float xCoordinate = [[points objectAtIndex:0] CGPointValue].x;

Я нашел это здесь: Как я могу легко добавить объекты CGPoint в NSArray? , опубликованный Джарретом Харди.

2 голосов
/ 05 октября 2013

Я решаю свою проблему следующим образом:


NSMutableArray *myArray = [[NSMutableArray alloc] init];
[myArray addObject:[NSValue valueWithCGPoint:myPoint]];

Спасибо Майклу-Дженсену за решение !

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...