高效的绘图存储方法?

时间:2011-03-22 22:23:22

标签: iphone objective-c drawing cgcontext

我正在开发一个基本的绘图应用程序,它有几个类。其中一个是“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
        }
    }

1 个答案:

答案 0 :(得分:2)

如果“行”只是数据模型中的一对点,那么这不会减慢你的速度。

你的性能问题是你正在重新绘制每一行被添加的东西,即O(n ^ 2)或非常具体的Schlemiel-the-Painter's algorithm

最简单的改进,假设您在UIView的-drawRect:内绘图,可能只会使包含新行的rect无效并重绘。根据起点和终点,你可以创建无效的矩形发送到-setNeedsDisplayInRect:,然后在你的drawRect中,查看你所有的行,并只画出那些落在rect里面的行。这会将您的绘制性能限制为线条的大小,并且在较小的程度上,“已经存在”的绘图。