Calculate controlPoints while drawing in iOS
Asked Answered
L

1

4

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

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

So I think, I am making some mistake in getting the control point.

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 me, the points which I am passing in the CGContextAddQuadCurveToPoint can be tweaked, but how to tweak that, I am not getting. I read docs to find control points for Bezier Curve, but I am not understanding.

So friends, please help me out understanding where I am going wrong.

Leggett answered 2/1, 2014 at 11:16 Comment(3)
You can use Catmull-Rom spline instead of bezeire curve to have a smooth curve #8703196Bingle
@amar, can you suggest how this code can be tweakedLeggett
ranjit check this url mobile.tutsplus.com/tutorials/iphone/… may this help you and gives you how to make efficient curves using Bezier CurveCulmination
S
4

The problem you're having is that when the user drags his finger slowly, the control points you get are too far apart, so you get large line segments rather than the small pixel changes that would give you a smooth-looking curve.

Calcualting Bezier control points from an existing curve is really hard, since the control points are not on the line.

Better to use Catmull-Rom curves. There is an excellent "Recipe" in Erica Sadun's OUTSTANDING book "The Advanced iOS 6 Developer's Cookbook" that includes working code on Catmull-Rom spline based smoothing. Catmull-Rom splines use control points that are on the curve.

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

Sibel answered 7/1, 2014 at 16:29 Comment(12)
Here here. Erica Sadun's books are awesome. Money well spent.Synapse
Hello @Duncan C thanks for your reply, So you are suggesting me to use Catmull-Rom splines and then find control pints and pass them into the quadCurve function, so everything remains same, only I need to calculate control points and pass. Is that what you meant, or is it something differentLeggett
No. Catmull-Rom splines have control points along the curve. You'd use Catmull-Rom splines to break your curve up into more straight line segments and not use cubic or quadratic Bezier curves at all.Sibel
Hello @DuncanC, So I should discard this code completely right? ok, I saw that code in 4.3, it is not drawing smooth curves.Leggett
Right, start over using Catmull-Rom smoothing. Buy the book.Sibel
Hello @DuncanC , please help me out with this #21028288Leggett
Hello @DuncanC, I gone through the sample code, the function catmull rom smoothes the given path with a certain granularity. So the path can be CGPath or UIBezierPath right? What I want to convey is that can I use the existing code and just pass my path to the function. Correct me if I am wrongLeggett
Hello @DuncanC, you say that in my present code, control points are not the curve. I didnt get this.Leggett
In Bezier curves, only the first and last point are actually on the curve. The middle control point(s) are not on the curve, but pull the curve towards them. There is no obvious way to come up with the locations of the control points to match an existing shape.Sibel
Hello @DuncanC, please look at this #21439086 I need your helpLeggett
Hello @DuncanC, please help me out https://mcmap.net/q/331846/-multitouch-tracking-issueLeggett
Hello @DuncanC, please look at this #21952774, Please help me outLeggett

© 2022 - 2024 — McMap. All rights reserved.