1

So I've encountered a rather interesting, and likely highly math related problem to do with apple's implementation of the Bezier Curve.

So to cut to the chase, I've got a UIBezierCurve. I've plotted 3 points to generate an curve. A left point, the control point and the right point. Here is an example:

UIBezierPath *bezierCurve = [UIBezierPath bezierPath];
[bezierCurve moveToPoint:leftCorner];
[bezierCurve addQuadCurveToPoint:rightCorner controlPoint:controlPoint];

Where leftCorner, rightCorner and controlPoint are all CGPoints. Its pretty much an upside down parabola (with the values I am using usually, although this likely doesn't matter, its a parabola in some fashion that would pass the vertical line test). Like this: https://www.wolframalpha.com/input/?i=graph+of+y+%3D+-x%5E2

Now what I want to do is gather a list of points along this bezierCurve. Not just the 3 points I used to create it. For example, I would like to have, lets say a fine-grained list of probably hundreds of points along the curve that are all evenly spaced.

How I approached solving this: Hill-climb algorithm. My implementation of it was basically to start at the left of the curve (left corner) and walk along the curve until I got to the right corner. While walking 1 unit to the right each time I would try to hug the curve using:

- (BOOL)containsPoint:(CGPoint)point

This worked reasonably well, I got a list of a few hundred points along the curve. The problem however is they are certainly not equally spaced (equidistant is likely the term I am looking for here). Where the slope of the curve is relatively flat I get many points, and they are reasonably evenly spaced. When the slope is large however I get very few points compared to the length of the line in those areas. Sometimes only a point or two in very steep areas (when there should be many).

How I think I should solve this problem is to go with my hill climb algorithm (doing a pass horizontally, by walking along the x-axis hugging the curve) and add a second pass vertically (walking along the y-axis, hugging the curve). And then merge those 2 sets of points by sorting by x-value, and then within each x-value I sort by y-value.

However I am thinking there must be an easier, trivial way to do this. On Android all you have to do on the similar class to UIBezierCurve (android's "Path" class) is:

for (int i = 0; i < pathMeasure.getLength(); i++) 
{
    float[] point = new float[2];
    float[] tangent = new float[2];

    boolean success = pathMeasure.getPosTan(i, point, tangent);

    if (success) 
    {
            curvePoints.add(new Point((int)point[0], (int)point[1]));
    }
}

In the end of that I basically have a list of points (curvePoints) that are all equidistant. PathMeasure is the class that works on android's Path (they are both built-in Android classes). I was hoping there was something similar to PathMeasure to easily get a list of equidistant points (of fine-grained granularity) on a UIBezierCurve and to avoid having to get heavy into the math of doing this all by hand. Is there something I'm missing?

Thanks!

Jordan Johns
  • 745
  • 2
  • 10
  • 20
  • @robmayoff I think that actually is along the lines of what I'm looking for. CGPathCreateCopyByDashingPath allows me to specify the level of how fine-grained the points are (distance apart) that appears to be equidistant. Going to look into that, thanks. – Jordan Johns Apr 30 '14 at 18:22
  • How important is it that the points are equidistant? See [Wikipedia](https://en.wikipedia.org/wiki/Bezier_curve#Quadratic_B.C3.A9zier_curves) for a formula where you plug in a parameter *t* between 0 and 1 and obtain a point on the curve. The points won't be spaced at equal intervals, but will look fairly regular nonetheless. If you really need equidistance, you'd have to measure distances along this path. For details on that, see [Equidistant points across Bezier curves](http://stackoverflow.com/q/10477/1468366). – MvG Apr 30 '14 at 19:09
  • Hi you get answer for this i am also struggling same please help me if got any solution regarding this – vijay Mar 18 '21 at 02:40

0 Answers0