Drawing Smooth Curves - Methods Needed

前端 未结 12 2242
长情又很酷
长情又很酷 2020-11-28 17:13

How do you smooth a set of points in an iOS drawing app WHILE MOVING? I have tried UIBezierpaths but all I get are jagged ends where they intersect, when I just shift the po

12条回答
  •  爱一瞬间的悲伤
    2020-11-28 18:07

    @Rakesh is absolutely right - you dont need to use Catmull-Rom algorithm if you just want a curved line. And the link he suggested does exacly that. So here's an addition to his answer.

    The code bellow does NOT use Catmull-Rom algorithm & granularity, but draws a quad-curved line (control points are calculated for you). This is essentially what's done in the ios freehand drawing tutorial suggested by Rakesh, but in a standalone method that you can drop anywhere (or in a UIBezierPath category) and get a quad-curved spline out of the box.

    You do need to have an array of CGPoint's wrapped in NSValue's

    + (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;
    }
    

    Here's the result: enter image description here

提交回复
热议问题