在时间获取路径的位置 [英] Get position of path at time

查看:24
本文介绍了在时间获取路径的位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有一种很好的方法来计算给定时间(从 0 到 1)的路径(CGPath 或 UIBezierPath)的位置?

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

以 CAShapeLayer 为例,您可以创建动画笔触末端.我想在任意时间知道该笔划结束的位置.

Using CAShapeLayer for example, one can create an animated stroke end. I want to know the position of that stroke end at arbitrary times.

提前致谢,阿德里安

推荐答案

您绝对可以将您的方法基于 CADisplayLink 和跟踪层.但是,如果您不介意自己做一点数学,那么解决方案并不太复杂.另外,您不必依赖于设置显示链接和额外的图层.事实上,您甚至不必依赖 QuartzCore.

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.

以下内容适用于任何 CGPathRef.在 UIBezierPath 的情况下,获取相同的 CGPath 属性:

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

  • 在要内省的路径上使用 CGPathApply 以及自定义 CGPathApplierFunction 函数.
  • 将为该路径的每个组件调用您的 CGPathApplierFunction.CGPathElement(应用程序的一个参数)将告诉您它是哪种路径元素以及构成该元素的点(控制点或端点).
  • 对于kCGPathElementMoveToPointkCGPathElementAddLineToPointkCGPathElementAddQuadCurveToPointkCGPathElementAddCurveToPoint,您将获得一分、二分、三分和四分> 分别.
  • 将这些点存储在您选择的内部表示中.您只需要为每个路径使用一次 CGPathApply,这一步非常快.
  • 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.

现在开始数学:

  • 根据您希望在 t 处找到位置的时间,获取元素(稍后会详细介绍)及其组成点.
  • 如果元素类型是kCGPathElementMoveToPoint,它是一个线性插值p0 + t * (p1 - p0)(对于x和y)
  • 如果元素类型是 kCGPathElementAddQuadCurveToPoint,则其二次 ((1 - t) * (1 - t)) * p0 + 2 * (1 - t) * t * p1 +t * t * p2
  • 如果元素类型是 kCGPathElementAddCurveToPoint,则它是三次贝塞尔曲线 ((1 - t) * (1 - t) * (1 - t)) * p0 + 3 * (1- t) * (1 - t) * t * p1 + 3 * (1 - t) * t * t * p2 + t * t * t * p3
  • 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

现在问题仍然存在,你如何找出t时间的路径元素.您可以假设每个路径元素获得相等的时间片,或者您可以计算每个元素的距离并考虑分数时间(前一种方法对我来说很好用).另外,不要忘记为所有先前的路径元素添加时间(您不必为这些元素找到插值).

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).

正如我所说,这只是为了完整性(以及 Apple 如何自己计算出这些东西),并且前提是您愿意进行数学计算.

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.

这篇关于在时间获取路径的位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆