1

I'm dealing with a CGPathRef that is a Bezier Curve. I'd like to get 100 evenly spaced X, Y coordinates on the path ref.

For instance, on this line, I'd like to get 100 Y values for evenly spaced X values.

CGPathRef Currently, I am creating a UIView and animating it with speed = 0.f then waiting for animation did stop and then getting the view's x,y coordinates:

CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
pathAnimation.calculationMode = kCAAnimationLinear;
pathAnimation.fillMode = kCAFillModeForwards;
pathAnimation.removedOnCompletion = NO;
pathAnimation.speed = 0.f;
pathAnimation.duration = 100;
// Get position 50
pathAnimation.timeOffset = 50;
pathAnimation.path = path;
pathAnimation.delegate = (id)self;

However, this has very poor performance when it's done a lot -- not to mention it's incredibly hacky. Is there a better way to do this?

BigCheesy
  • 1,128
  • 8
  • 14
  • are estimate values enough? – Nils Ziehn Sep 04 '14 at 18:44
  • 1
    Note that in general the bezier path can multiple points with the same X-coordinate, so that determining Y from X is not unique. For the exact solution you have to solve cubic equations. Here is a similar but simpler problem: http://stackoverflow.com/questions/16755823/finding-a-point-on-a-path – Martin R Sep 04 '14 at 18:45
  • @NilsZiehn yes, depending on how close the estimates are. – BigCheesy Sep 04 '14 at 19:14
  • @MartinR yes. In my case I won't ever have multiple X coordinates -- but I guess I should rephrase my question as: How do you get the X, Y coordinates along an even offset along a CGPathRef? – BigCheesy Sep 04 '14 at 19:16
  • @MartinR In your other answer, it makes sense except what do I do if the bezier curve was built with 100 points? Do I still only have a P0, P1, P2, P3? If so, what are P0, P1, P2, P3 for lets say point 50 in the line? Or, should I have P0...P100? – BigCheesy Sep 04 '14 at 19:30
  • And one other question -- If I am calculating 10,000 different points, would expect the bezier math to be faster than letting ios do the animation and then grabbing the image frame? – BigCheesy Sep 04 '14 at 19:31
  • If you don't want to go throught the hassel of inverting your equation you can just forward calculate the value for 't' from 0-1 with very small steps (e.g. 0.000001) and then use the values that are closest to your wanted steps. This is actually ultra fast – Nils Ziehn Sep 05 '14 at 09:28
  • Oh, and you have to iterate through the different slices of your bezier path. – Nils Ziehn Sep 05 '14 at 09:30
  • @NilsZiehn Could you help me understand what P0 - P3 would be for a given "slice" of the bezier path? Let's say I have 100 data points for my bezier curve, and I want to know the X,Y coordinates at segment 50.5. Is P0 = pt 49, P1 = pt 50, P2 = pt 51, P3 = pt 52 and T = 0.5? – BigCheesy Sep 05 '14 at 14:48
  • no, you have to go through your bezier path's slices. You can do this using the CGPathRef of your UIBezierPath: CGPathRef yourCGPath = bezierPath.CGPath; and then CGPathApply. You should look them up in Apple's doku. Are you sure that your bezier path will be not be an overdefined function (having more than one y value for a given x) ? If I have time tonight I can give you some more code. – Nils Ziehn Sep 05 '14 at 14:55
  • @NilsZiehn Yeah I'm positive it will not be an overdefined function. The CGPathRef is a line graph from CorePlot. Will I be getting an NSBezierPath from CGPathApply? If so, should I be using -elementAtIndex:associatedPoints to get P0->P3? Should the path only have 4 elements, where indices 0-3 correspond to P0->P3? Does the type that's returned (NSBezierPathElement enum) define which points would be start/end vs. control? Thanks for your help. – BigCheesy Sep 05 '14 at 15:13
  • @NilsZiehn I go this going and it's two orders of magnitude faster than my hacky animation approach. Thanks so much for your help! I'll post code in a bit. – BigCheesy Sep 06 '14 at 16:02
  • Looks like I can't paste my code in here :| – BigCheesy Sep 06 '14 at 22:50

0 Answers0