Get position of path at time

前端 未结 3 1841
终归单人心
终归单人心 2021-01-13 06:17

is there a nice way to calculate the position of a path (CGPath or UIBezierPath) at a given time (from 0 to 1)?

Using CAShapeLayer for example, one can create an ani

3条回答
  •  梦谈多话
    2021-01-13 06:58

    You can definitely base your approach on the CADisplayLink and a tracking layer. However, if you don't mind doing a little bit of math on your own, the solution is not too complicated. Plus, you wont have to depend on setting up a display link and extra layers. In fact, you dont even have to depend on QuartzCore.

    The following will work for any CGPathRef. In case of a UIBezierPath, fetch the CGPath property of the same:

    • Use CGPathApply on the path you want to introspect along with a custom CGPathApplierFunction function.
    • Your CGPathApplierFunction will be invoked for each component of that path. The CGPathElement (an argument to the applier) will tell you what kind of a path element it is along with the points that make that element (control points or endpoints).
    • You will be given one, two, three and four points for kCGPathElementMoveToPoint, kCGPathElementAddLineToPoint, kCGPathElementAddQuadCurveToPoint and kCGPathElementAddCurveToPoint respectively.
    • Store these points internally in a representation of your choosing. You only need to use the CGPathApply once per path and this step is extremely fast.

    Now, onto the math:

    • Based on the time you wish to find the position at, say t, get the element (more on this later) and its constituent points.
    • If the element type is kCGPathElementMoveToPoint, its a linear interpolation p0 + t * (p1 - p0) (for x and y)
    • If the element type is kCGPathElementAddQuadCurveToPoint, its quadratic ((1 - t) * (1 - t)) * p0 + 2 * (1 - t) * t * p1 + t * t * p2
    • If the element type is kCGPathElementAddCurveToPoint, its a cubic bezier ((1 - t) * (1 - t) * (1 - t)) * p0 + 3 * (1 - t) * (1 - t) * t * p1 + 3 * (1 - t) * t * t * p2 + t * t * t * p3

    Now the question remains, how do you figure out the path element at time t. You can assume each path element gets an equal time slice or you can calculate the distance of each element and account for the fractional time (the former approach works fine for me). Also, don't forget to add the times for all previous path elements (you dont have to find the interpolations for these).

    As I said, this is just for completeness (and likely how Apple figures out this stuff out themselves) and only if you are willing to do the math.

提交回复
热议问题