Wednesday, June 5, 2013

UIBezierPath addCurveToPoint example in Objective C (iOS).

UIBezierPath addCurveToPoint

Appends a cubic Bézier curve to the receiver’s path.

- (void)addCurveToPoint:(CGPoint)endPoint controlPoint1:(CGPoint)controlPoint1 controlPoint2:(CGPoint)controlPoint2

Parameters of [UIBezierPath addCurveToPoint]
The end point of the curve.
The first control point to use when computing the curve.
The second control point to use when computing the curve.

Discussion of [UIBezierPath addCurveToPoint]
This method appends a cubic Bézier curve from the current point to the end point specified by the endPoint parameter. The two control points define the curvature of the segment. Figure 2 shows an approximation of a cubic Bézier curve given a set of initial points. The exact curvature of the segment involves a complex mathematical relationship between all of the points and is well documented online.

Figure 2 A cubic Bézier curve
UIBezierPath addCurveToPoint
You must set the path’s current point (using the moveToPoint: method or through the previous creation of a line or curve segment) before you call this method. If the path is empty, this method does nothing. After adding the curve segment, this method updates the current point to the value in point.
UIBezierPath addCurveToPoint example.
// Get points from Bezier Curve
void getPointsFromBezier(void *info, const CGPathElement *element)
    NSMutableArray *bezierPoints = (__bridge NSMutableArray *)info;   

    // Retrieve the path element type and its points
    CGPathElementType type = element->type;
    CGPoint *points = element->points;

    // Add the points if they're available (per type)
    if (type != kCGPathElementCloseSubpath)
        [bezierPoints addObject:VALUE(0)];
        if ((type != kCGPathElementAddLineToPoint) &&
            (type != kCGPathElementMoveToPoint))
            [bezierPoints addObject:VALUE(1)];
    if (type == kCGPathElementAddCurveToPoint)
        [bezierPoints addObject:VALUE(2)];

Example of [UIBezierPath addCurveToPoint].
- (void)drawRect:(CGRect)rect
#define commonY 117

    CGPoint point1 = CGPointMake(20, 20);
    CGPoint point2 = CGPointMake(100, commonY);
    CGPoint point3 = CGPointMake(200, 50);
    CGPoint controlPoint1 = CGPointMake(50, 60);
    CGPoint controlPoint2 = CGPointMake(20, commonY);
    CGPoint controlPoint3 = CGPointMake(200, commonY);
    CGPoint controlPoint4 = CGPointMake(250, 75);

    UIBezierPath *path1 = [UIBezierPath bezierPath];
    UIBezierPath *path2 = [UIBezierPath bezierPath];

    [path1 setLineWidth:3.0];
    [path1 moveToPoint:point1];
    [path1 addCurveToPoint:point2 controlPoint1:controlPoint1 controlPoint2:controlPoint2];
    [[UIColor blueColor] set];
    [path1 stroke];

    [path2 setLineWidth:3.0];
    [path2 moveToPoint:point2];
    [path2 addCurveToPoint:point3 controlPoint1:controlPoint3 controlPoint2:controlPoint4];
    [[UIColor orangeColor] set];
    [path2 stroke];

UIBezierPath addCurveToPoint example.
- (UIBezierPath *)curvePath {
    return [[curvePath retain] autorelease];
- (void)setCurvePath:(UIBezierPath *)newPath {
    id tmp = curvePath;
    curvePath = [newPath retain];
    [tmp release];
    state = BezierStateNone;
    [self setNeedsDisplay];
- (void)_updateCurve {
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:startPt];
    [path addCurveToPoint:endPt controlPoint1:cPt1 controlPoint2:cPt2];

End of UIBezierPath addCurveToPoint example article.