Эффективный метод хранения чертежей?

Я разрабатываю базовое приложение для рисования, в котором есть несколько классов. Один из них - это класс Line, который хранит некоторую информацию о линии, которую может нарисовать пользователь. Когда пользователь перемещает курсор по экрану, линия создается для каждого движения его пальца, поэтому линия рисуется после его пальца. Я сохраняю все строковые объекты в массиве NSArray и перерисовываю каждый раз, когда что-то меняется. Однако, поскольку массив становится все больше и в конечном итоге начинает замедляться. Есть ли способ просто нарисовать новые линии или лучший механизм хранения для линий?

РЕДАКТИРОВАТЬ: Прочтите ответ ниже, но setNeedsDisplayInRect:, похоже, не работает. Я называю это так:

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    for (UITouch *t in touches) {
        //add line to array w/ x and y values from touch
        [self setNeedsDisplayInRect:[self rectForLine:line]];
    }
}

-(CGRect)rectForLine:(Line*)line {
    CGFloat x1 = [line begin].x;
    CGFloat y1 = [line begin].y;
    CGFloat x2 = [line end].x;
    CGFloat y2 = [line end].y;
    CGFloat originX = (x1>x2) ? x1 : x2;
    CGFloat originY = (y1<y2) ? y1 : y2;
    CGFloat diffX = ((x1>x2) ? x1 : x2) - originX;
    CGFloat diffY = ((y1>x2) ? y1 : y2) - originY;
    return CGRectMake(originX, originY, diffX, diffY);
}

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(context, 10.0);
    CGContextSetLineCap(context, kCGLineCapRound);
    //[[UIColor blackColor] set];
    for (Line *line in completeLines) {
        if (CGRectContainsPoint(rect, [line begin]) && CGRectContainsPoint(rect, [line end])) {
            //draw line onto the screen
        }
    }

person Jumhyn    schedule 22.03.2011    source источник
comment
Пожалуйста, определите, похоже, не работает. Есть как минимум пара проблем с вашей реализацией, но расскажите мне, что вы видите в первую очередь, чтобы мы знали, с чего начать.   -  person Ben Zotto    schedule 23.03.2011
comment
Ничего не нарисовано, пока я не позвоню setNeedsDisplay. Если вынуть это, вообще ничего не привлекает.   -  person Jumhyn    schedule 23.03.2011
comment
1. Действительно ли ваши поврежденные прямые зубы выглядят разумно? Вызывается drawRect? 2. В вашем rectForLine есть по крайней мере одна очевидная опечатка в вычислении diffY без комментариев к остальной части алгоритма. 3. Ваш тест на то, находится ли линия в прямоугольнике, неверен - вам нужно проверить, проходит ли линия и через прямоугольник, а не только если она начинается или заканчивается в нем. 4. Если у вас есть линии шириной 10 пикселей, вам нужно будет заполнить внешнюю часть недопустимого прямоугольника, чтобы учесть это.   -  person Ben Zotto    schedule 23.03.2011
comment
Исправлены 1, 2 и 4, но я не уверен, как приступить к решению 3. Не могли бы вы помочь с этим?   -  person Jumhyn    schedule 23.03.2011
comment
Получите ограничивающую рамку линии (которую вы знаете, как это сделать) и вычислите пересечение этой линии и прямоугольника отрисовки с помощью CGRectIntersectsRect. Если он пересекается, нужно его нарисовать.   -  person Ben Zotto    schedule 23.03.2011
comment
Красиво, работает отлично. Спасибо!   -  person Jumhyn    schedule 23.03.2011


Ответы (1)


Если «линия» - это всего лишь пара точек в вашей модели данных, это не та часть, которая вас замедляет.

Ваша проблема с перфомансом заключается в том, что вы перерисовываете все это в каждой добавляемой строке, которая равна O (n ^ 2) или, в частности, алгоритм Шлемиля-художника.

Самое простое улучшение, предполагающее, что вы рисуете внутри -drawRect: UIView, вероятно, состоит только в том, чтобы сделать недействительным и перерисовать прямоугольник, содержащий новую строку. На основе начальной и конечной точек вы можете создать недопустимый прямоугольник для отправки в -setNeedsDisplayInRect:, а затем в своем drawRect просмотреть все свои линии и нарисовать только те, которые попадают в прямоугольник. Это ограничивает вашу производительность рисования размером линий и, в гораздо меньшей степени, рисованием, которое «уже есть».

person Ben Zotto    schedule 22.03.2011