开发者

Smooth writing on iPad

I'm currently working on a iPad project where I need the functionality to let the user write on a piece of paper with a stylus.

I've tested a couple of styluses and found out that the bamboo was the best. They also have a free application which you can use to write.

The problem I'm facing is that the method I use does not delivers smooth curves. The bamboo paper app provides perfect looking lines. This is the code I have so far:

- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    UIGraphicsBeginImageContext(self.frame.size);

    // draw accumulated lines
    if ([self.lines count] > 0) {
        for (Line *tempLine in self.lines){
            CGContextSetAlpha(context, tempLine.opacity);
            CGContextSetStrokeColorWithColor(context, tempLine.lineColor.CGColor);
            CGContextSetLineWidth(context, tempLine.lineWidth);
            CGContextSetLineCap(context, kCGLineCapRound);
            CGContextSetLineJoin(context, kCGLineJoinRound);
            CGContextAddPath(context, tempLine.linePath);
            CGContextStrokePath(context);

            }
    }

    //draw current line
    CGContextSetAlpha(context, self.currentLine.opacity);


    CGContextSetStrokeColorWithColor(context, self.currentLine.lineColor.CGColor);
    CGContextSetLineWidth(context, self.currentLine.lineWidth);
    CGContextSetLineCap(context, kCGLineCapRound);
    CGContextSetLineJoin(context, kCGLineJoinRound);
    CGContextBeginPath(context);
    CGContextAddPath(context, self.currentLine.linePath);
    CGContextStrokePath(context);


    UIGraphicsEndImageContext();


}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    CGPoint cPoint = [touch locationInView:self];

    CGPathMoveToPoint(self.currentLine.linePath, NULL, cPoint.x, cPoint.y);

    [self setNeedsDisplay];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];   
    CGPoint currentPoint = [touch locationInView:self];

    CGPathAddLineToPoint(self.currentLine.linePath, NULL, currentPoint.x, currentPoint.y);

    [self setNeedsDisplay];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 开发者_JAVA百科{  
    UITouch *touch = [touches anyObject];
    CGPoint cPoint = [touch locationInView:self];
    CGPathAddLineToPoint(self.currentLine.linePath, NULL, cPoint.x, cPoint.y);

    [self setNeedsDisplay];
    [self.lines addObject:self.currentLine];
    Line *nextLine = [[Line alloc] initWithOptions:self.currentLine.lineWidth color:self.currentLine.lineColor opacity:self.currentLine.opacity];
    self.currentLine = nextLine;
    [nextLine release];
}

Here are the images that makes it clear what problem I'm facing. This is the image what gets generated when writing with the code provided above:

Smooth writing on iPad

This is the image if I write the same thing on the Mamboo paper app:

Smooth writing on iPad

Does anyone have an idea how to get the nice writing like in the mamboo app?


Instead of joining the points using straight lines (CGPathAddLineToPoint) you should try using bezier curves: CGPathAddCurveToPoint or CGPathAddQuadCurveToPoint.

This is what will do the smoothing.


If you are not familliar with bézier curves, you will probably find the wikipedia page about Bézier curves interesting (not specifically the math equations, but look at the sketches and animated images). It will give your the general idea of how control points affect the smoothing of the lines around the key points of your line.

For your case, Quadratic curves (only one control point for each subsegment between two of your key points) should be sufficient.

Smooth writing on iPad

(One line from P0 to P1, smoothed using control point P1)


One example (out of the box, only a suggestion out of my mind, never tested, adapt the coefficients to your needs) to compute this control point C between each of your keypoints A and B is to make the AC being, say, 2/3rd of the length of AB, and (AB,AC) making an angle of 30 degrees or sthg similar.

You may even propose in the settings of your app to adjust the smoothing strengh with a slider, which will impact the values you choose to compute each control points and see which coefficients fits best.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜