1

Let's say I have a random bezier path, like this:

let bezierPath = UIBezierPath()
bezierPath.move(to: CGPoint(x: 3, y: 0.84))
bezierPath.addCurve(to: CGPoint(x: 11, y: 8.84), controlPoint1: CGPoint(x: 3, y: 1.84), controlPoint2: CGPoint(x: 9, y: 4.59))
// [...]
bezierPath.addCurve(to: CGPoint(x: 3, y: 0.84), controlPoint1: CGPoint(x: 7, y: 4.84), controlPoint2: CGPoint(x: 3, y: -0.16))
bezierPath.close()

I would like to create a function that compute a CGPoint for a given percentage, where 0% is the first point and 100% the last point of the bezierPath:

extension UIBezierPath {
    func getPointFor(percentage: Float) -> CGPoint {
        //Computation logic
        return result
    }
}

I have found this post but the solution doesn't allow me to get all points (position at 15.5% of the path for example).

Is there a way to do this?

Community
  • 1
  • 1
Bogy
  • 944
  • 14
  • 30

1 Answers1

4

I have found a solution written in objective-c. You can find the source code here.

I manage to use it by using a bridging header :

#ifndef bridging_header_h
#define bridging_header_h

#import "UIBezierPath+Length.h"

#endif /* bridge_header_h */

And you can use the two functions like this:

print("length=\(bezierPath.length())")
for i in 0...100 {
    let percent:CGFloat = CGFloat(i) / 100.0
    print("point at [\(percent)]=\(bezierPath.point(atPercentOfLength: percent))")
}

output:

length=143.316117804497
point at [0.0]=(3.0, 0.839999973773956)
point at [0.01]=(3.26246070861816, 1.29733419418335)
point at [0.02]=(3.97137236595154, 1.91627132892609)
point at [0.03]=(5.00902938842773, 2.69386911392212)
[...]
point at [0.99]=(3.27210903167725, 0.765813827514648)
point at [1.0]=(3.0, 0.839999973773956)
Bogy
  • 944
  • 14
  • 30
  • 3
    Keep in mind that code subdivides the curve into 100 segments to approximate the length. That may be fine for many cases, but it's an approximation and for some extreme curves may not be a good approximation. You may have to tweak the number of iterations depending on your use. It's worth studying that code and understanding how it works if you need to do anything important with it. – Rob Napier Nov 08 '16 at 01:48
  • 1
    It's a good point to mention and to keep in mind. For my needs, this approximation is ok but any other solutions are welcome :) – Bogy Nov 08 '16 at 08:05