How to get a list of points from a UIBezierPath? How to get a list of points from a UIBezierPath? ios ios

How to get a list of points from a UIBezierPath?


You might try this:

UIBezierPath *yourPath; // Assume this has some points in itCGPath yourCGPath = yourPath.CGPath;NSMutableArray *bezierPoints = [NSMutableArray array];CGPathApply(yourCGPath, bezierPoints, MyCGPathApplierFunc);

The path applier function will be handed each of the path's path elements in turn.
Check out CGPathApplierFunction and CGPathApply.

The path applier function might look something like this

void MyCGPathApplierFunc (void *info, const CGPathElement *element) {    NSMutableArray *bezierPoints = (NSMutableArray *)info;    CGPoint *points = element->points;    CGPathElementType type = element->type;    switch(type) {        case kCGPathElementMoveToPoint: // contains 1 point            [bezierPoints addObject:[NSValue valueWithCGPoint:points[0]]];            break;                case kCGPathElementAddLineToPoint: // contains 1 point            [bezierPoints addObject:[NSValue valueWithCGPoint:points[0]]];                        break;                case kCGPathElementAddQuadCurveToPoint: // contains 2 points            [bezierPoints addObject:[NSValue valueWithCGPoint:points[0]]];            [bezierPoints addObject:[NSValue valueWithCGPoint:points[1]]];                        break;                case kCGPathElementAddCurveToPoint: // contains 3 points            [bezierPoints addObject:[NSValue valueWithCGPoint:points[0]]];            [bezierPoints addObject:[NSValue valueWithCGPoint:points[1]]];            [bezierPoints addObject:[NSValue valueWithCGPoint:points[2]]];            break;                case kCGPathElementCloseSubpath: // contains no point            break;    }}


@Moritz Great answer! To find a Swift like solution I strumbled across an approach in this post and implemented a CGPath extension like this to get the points from the path:

extension CGPath {    func points() -> [CGPoint]    {        var bezierPoints = [CGPoint]()        self.forEach({ (element: CGPathElement) in            let numberOfPoints: Int = {                switch element.type {                case .MoveToPoint, .AddLineToPoint: // contains 1 point                    return 1                case .AddQuadCurveToPoint: // contains 2 points                    return 2                case .AddCurveToPoint: // contains 3 points                    return 3                case .CloseSubpath:                    return 0                }            }()            for index in 0..<numberOfPoints {                let point = element.points[index]                bezierPoints.append(point)            }        })        return bezierPoints    }    func forEach(@noescape body: @convention(block) (CGPathElement) -> Void) {        typealias Body = @convention(block) (CGPathElement) -> Void        func callback(info: UnsafeMutablePointer<Void>, element: UnsafePointer<CGPathElement>) {            let body = unsafeBitCast(info, Body.self)            body(element.memory)        }        let unsafeBody = unsafeBitCast(body, UnsafeMutablePointer<Void>.self)        CGPathApply(self, unsafeBody, callback)    }}


I think you were trying to do something like this:

https://math.stackexchange.com/questions/26846/is-there-an-explicit-form-for-cubic-bézier-curves

y=u0(1−x^3)+3u1(1−x^2)x+3u2(1−x)x^2+u3x^3

This is my method for printing all values of that function.

- (void)logXY {    float u0 = 0;    float u1 = 0.05;    float u2 = 0.25;    float u3 = 1;    for (float x = 0; x <= 10.0; x = x + 0.1) {        float y = u0 * (1 - x * x * x) + 3 * u1 * (1 - x * x) * x + 3 * u2 * (1 - x) * x * x + u3 * x * x * x;        NSLog(@"x: %f\ty: %f", x, y);    }}

And output is:

x: 0.000000 y: 0.000000x: 0.100000 y: 0.022600x: 0.200000 y: 0.060800x: 0.300000 y: 0.115200x: 0.400000 y: 0.186400x: 0.500000 y: 0.275000x: 0.600000 y: 0.381600x: 0.700000 y: 0.506800x: 0.800000 y: 0.651200x: 0.900000 y: 0.815400x: 1.000000 y: 1.000000x: 1.100000 y: 1.205600x: 1.200000 y: 1.432800x: 1.300000 y: 1.682200x: 1.400000 y: 1.954401x: 1.500000 y: 2.250001x: 1.600000 y: 2.569601x: 1.700000 y: 2.913801x: 1.800000 y: 3.283201x: 1.900000 y: 3.678401x: 2.000000 y: 4.100001x: 2.100000 y: 4.548601x: 2.200000 y: 5.024800x: 2.300000 y: 5.529200x: 2.400000 y: 6.062399x: 2.500000 y: 6.625000x: 2.600000 y: 7.217597x: 2.700000 y: 7.840797x: 2.799999 y: 8.495197x: 2.899999 y: 9.181394x: 2.999999 y: 9.899996