Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iPhone smooth sketch drawing algorithm

I am working on a sketching app on the iPhone. I got it working but not pretty as seen here enter image description here

And I am looking for any suggestion to smooth the drawing Basically, what I did is when user places a finger on the screen I called

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event  

then I collect a single touch in an array with

- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 

and when the user lefts a finger from the screen, I called

- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 

then I draw all the points in the array using

NSMutableArray *points = [collectedArray points];     CGPoint firstPoint; [[points objectAtIndex:0] getValue:&firstPoint];  CGContextMoveToPoint(context, firstPoint.x, firstPoint.y); CGContextSetLineCap(context, kCGLineCapRound); CGContextSetLineJoin(context, kCGLineJoinRound);  for (int i=1; i < [points count]; i++) {     NSValue *value = [points objectAtIndex:i];     CGPoint point;     [value getValue:&point];         CGContextAddLineToPoint(context, point.x, point.y);  }   CGContextStrokePath(context); UIGraphicsPushContext(context); 

And now I want to improve the drawing tobe more like "Sketch Book" App enter image description here

I think there is something to do with signal processing algorithm to rearrange all the points in the array but I am not sure. Any Help would be much appreciated.

Thankz in advance :)

like image 456
Suwitcha Sugthana Avatar asked Feb 22 '11 09:02

Suwitcha Sugthana


Video Answer


2 Answers

CGPoint midPoint(CGPoint p1, CGPoint p2) {      return CGPointMake((p1.x + p2.x) * 0.5, (p1.y + p2.y) * 0.5);  }  -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {      UITouch *touch = [touches anyObject];      previousPoint1 = [touch previousLocationInView:self];     previousPoint2 = [touch previousLocationInView:self];     currentPoint = [touch locationInView:self];  }  -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {      UITouch *touch = [touches anyObject];      previousPoint2 = previousPoint1;     previousPoint1 = [touch previousLocationInView:self];     currentPoint = [touch locationInView:self];       // calculate mid point     CGPoint mid1 = midPoint(previousPoint1, previousPoint2);      CGPoint mid2 = midPoint(currentPoint, previousPoint1);      UIGraphicsBeginImageContext(self.imageView.frame.size);     CGContextRef context = UIGraphicsGetCurrentContext();     [self.imageView.image drawInRect:CGRectMake(0, 0, self.imageView.frame.size.width, self.imageView.frame.size.height)];      CGContextMoveToPoint(context, mid1.x, mid1.y);     // Use QuadCurve is the key     CGContextAddQuadCurveToPoint(context, previousPoint1.x, previousPoint1.y, mid2.x, mid2.y);       CGContextSetLineCap(context, kCGLineCapRound);     CGContextSetLineWidth(context, 2.0);     CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0);     CGContextStrokePath(context);      self.imageView.image = UIGraphicsGetImageFromCurrentImageContext();     UIGraphicsEndImageContext();  } 
like image 112
kyoji Avatar answered Sep 23 '22 07:09

kyoji


The easiest way to smooth a curve like this is to use a Bezier curve instead of straight line segments. For the math behind this, see this article (pointed to in this answer), which describes how to calculate the curves required to smooth a curve that passes through multiple points.

I believe that the Core Plot framework now has the ability to smooth the curves of plots, so you could look at the code used there to implement this kind of smoothing.

There's no magic to any of this, as these smoothing routines are fast and relatively easy to implement.

like image 32
Brad Larson Avatar answered Sep 20 '22 07:09

Brad Larson