Calculate breakpoints when drawing in iOS

I am working on a graphical application where the user can draw / write with a finger or stylus. For this, I mentioned the code from https://github.com/yusenhan/Smooth-Line-View in my application.

The problem that I am facing is that writing sometimes, when you write very close, is not very smooth.

So, I think I'm wrong in getting a breakpoint.

Below is my code

// Find the midpoint

 CGPoint midPoint(CGPoint p1, CGPoint p2) { return CGPointMake((p1.x + p2.x) * 0.5, (p1.y + p2.y) * 0.5); } #pragma mark Gesture handle -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject]; //LocationInView returns the current location of the reciever in coordinate system of the given View. m_previousPoint1 = [touch locationInView:self]; m_previousPoint2 = [touch locationInView:self]; m_currentPoint = [touch locationInView:self]; [self touchesMoved:touches withEvent:event];} -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { //AnyObject:- Returns one of the objects in the set, or nil if the set contains no objects. UITouch *touch = [touches anyObject]; m_previousPoint2 = m_previousPoint1; m_previousPoint1 = m_currentPoint; m_currentPoint = [touch locationInView:self]; if(m_drawStep != ERASE) { m_drawStep = DRAW; m_drawing = TRUE; } } -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0.0);//creates a graphics context suitable for use as an image(size of the image,opquae,scale, if scale = 0.0, means platform will take care of scaling) [self.layer renderInContext:UIGraphicsGetCurrentContext()]; m_curImage = UIGraphicsGetImageFromCurrentImageContext();// to turn the context into a UIImage UIGraphicsEndImageContext(); } - (void)drawRect:(CGRect)rect { CGPoint mid1 = midPoint(m_previousPoint1, m_previousPoint2); CGPoint mid2 = midPoint(m_currentPoint, m_previousPoint1); [m_curImage drawAtPoint:CGPointMake(0, 0)]; CGContextRef context = UIGraphicsGetCurrentContext();//Get a reference to current context(The context to draw) [self.layer renderInContext:context]; //Simply keep referring to this context in below functions with proper arguments. CGContextMoveToPoint(context, mid1.x, mid1.y);//Position the current point CGContextAddQuadCurveToPoint(context, m_previousPoint1.x, m_previousPoint1.y, mid2.x, mid2.y); CGContextSetLineCap(context, kCGLineCapRound); CGContextSetBlendMode(context, kCGBlendModeNormal); CGContextSetLineJoin(context, kCGLineJoinRound); CGContextSetLineWidth(context, self.lineWidth); CGContextSetStrokeColorWithColor(context, self.lineColor.CGColor); CGContextSetShouldAntialias(context, YES); CGContextSetAllowsAntialiasing(context, YES); CGContextSetAlpha(context, self.lineAlpha); CGContextSetFlatness(context, 0.6); CGContextStrokePath(context);//paints(fills) the line along the current path. } 

According to my words, the points that I pass to CGContextAddQuadCurveToPoint can be configured, but I do not get how to configure this. I read the docs to find breakpoints for the Bezier Curve , but I don't understand.

So friends, please help me understand what I'm wrong about.

+3
ios core-graphics uibezierpath cgcontext cgpath
Jan 02 '14 at 11:16
source share
1 answer

The problem you are facing is that when the user slowly pulls his finger, the control points you get are too far apart, so you get large line segments, not small pixel changes, which will give you a smooth curve .

The calculation of BΓ©zier control points from an existing curve is really difficult, because the control points are not on the line.

Better to use Catmull-Rom curves. Erica Sadun OUTSTANDING has a great Recipe for the book β€œExtended Developers Book for iOS 6 Developers,” which includes Catmull-Rom splice-based smoothing code. Catmull-Rom alloys use breakpoints that are on the curve.

I highly recommend buying this book. The sample code for Recipe 4.3 will do exactly what you want.

+3
Jan 07 '14 at 16:29
source share



All Articles