How can I get all points in CGPath curve or quad curve

Vamshi picture Vamshi · May 8, 2009 · Viewed 8.2k times · Source

I have made a quad curve path using the method CGPathAddQuadCurveToPoint. I got the path perfectly. But, I want to know all the coordinate points which are participated in the path.

Is there a way to retrieve all the coordinate points in a path?

If not do u have any other solution for retrieving all the points in a curve mathematically.

Thanks in advance, Vamshi

Answer

George C. picture George C. · Jul 27, 2012

You can do this using the wykobi C++ library routine for cubic bezier curves. Wykobi's library supports quadratic Bezier curves also.

Of course as someone pointed out you don't want all the points (although not impossible, it would just take infinite time :). Wykobi makes it easy to get a certain number of points -- if your start, c1, c2, and end points (where c1, c2 are the control points) are exactly the same as the ones given to CGContextAddCurveToPoint then the points will lie perfectly on the line drawn by core graphics -- so you can do things like draw a pattern at several points on the path.

See: http://www.codeproject.com/Articles/22568/Computational-Geometry-C-and-Wykobi

Also, after I started using wykobi I heard that there is a similar, maybe even better library that is part of Boost, but have not checked it out yet.

I created a C++ Class WPoint as a bridge between wykobi points and CGPoints (C++ fun!). Here's some code (without WPoint, but you can imagine that it is exactly the same layout as a CGPoint so if you do the right cast you can convert easily.

        NSMutableArray* result = [[NSMutableArray alloc] init];
        wykobi::cubic_bezier<CGFloat,2> bezier;
        bezier[0] = (WPoint)p1;  // start point, in CG we did a CGMoveToPoint
        bezier[1] = (WPoint)b1i; // control 1
        bezier[2] = (WPoint)b2i; // control 2
        bezier[3] = (WPoint)p2;  // end point

        std::vector<WPoint> point_list;
        int numPoints = p2.dist(p3) * pointDensity;
        // *** here's the magic ***
        wykobi::generate_bezier(bezier,std::back_inserter(point_list), numPoints);

        for (int i=0; i<numPoints; i++) {
            CGPoint p = (CGPoint)(point_list[i]);
            [result addObject:[NSValue valueWithCGPoint:p]];
        }

// result has your points!

Here's a link to the Boost geometry library: http://www.boost.org/doc/libs/1_47_0/libs/geometry/doc/html/geometry/introduction.html