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

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

问题描述

是否有一种很好的方法来计算给定时间(从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天全站免登陆