Draw Graph curves with UIBezierPath

Abid Hussain picture Abid Hussain · Dec 5, 2012 · Viewed 23.8k times · Source

I'm drawing a graph in my application. My problem is that I want to draw line joining vertex points as curves. Currently I'm drawing them with UIBezierPath's function addLineToPoint:. I want to draw them as curves. I'm well aware that UIBezierPath has following two functions to support this feature.

Cubic curve:addCurveToPoint:controlPoint1:controlPoint2: Quadratic curve:addQuadCurveToPoint:controlPoint:

But problem is that I don't have control points. All i have is two end points. Neither I found a method/formula to determine control points. Can anyone help me here? I will appreciate if someone can suggest some alternative...

Answer

user1244109 picture user1244109 · Aug 13, 2014

Expand on Abid Hussain's answer on Dec 5 '12.

i implemeted the code, and it worked but result looked like that: enter image description here

With little adjustment, i was able to get what i wanted: enter image description here

What i did was addQuadCurveToPoint to mid points as well, using mid-mid points as control points. Below is the code based on Abid's sample; hope it helps someone.

+ (UIBezierPath *)quadCurvedPathWithPoints:(NSArray *)points
{
    UIBezierPath *path = [UIBezierPath bezierPath];

    NSValue *value = points[0];
    CGPoint p1 = [value CGPointValue];
    [path moveToPoint:p1];

    if (points.count == 2) {
        value = points[1];
        CGPoint p2 = [value CGPointValue];
        [path addLineToPoint:p2];
        return path;
    }

    for (NSUInteger i = 1; i < points.count; i++) {
        value = points[i];
        CGPoint p2 = [value CGPointValue];

        CGPoint midPoint = midPointForPoints(p1, p2);
        [path addQuadCurveToPoint:midPoint controlPoint:controlPointForPoints(midPoint, p1)];
        [path addQuadCurveToPoint:p2 controlPoint:controlPointForPoints(midPoint, p2)];

        p1 = p2;
    }
    return path;
}

static CGPoint midPointForPoints(CGPoint p1, CGPoint p2) {
    return CGPointMake((p1.x + p2.x) / 2, (p1.y + p2.y) / 2);
}

static CGPoint controlPointForPoints(CGPoint p1, CGPoint p2) {
    CGPoint controlPoint = midPointForPoints(p1, p2);
    CGFloat diffY = abs(p2.y - controlPoint.y);

    if (p1.y < p2.y)
        controlPoint.y += diffY;
    else if (p1.y > p2.y)
        controlPoint.y -= diffY;

    return controlPoint;
}