有没有一种很好的方法来计算给定时间(从 0 到 1)的路径(CGPath 或 UIBezierPath)的位置?
例如,使用 CAShapeLayer,可以创建动画笔划末端。 我想知道任意时间笔划结束的位置。
提前致谢,阿德里安
最佳答案
您绝对可以将您的方法建立在 CADisplayLink 和跟踪层的基础上。但是,如果您不介意自己做一点数学运算,那么解决方案并不太复杂。另外,您不必依赖于设置显示链接和额外的图层。事实上,您甚至不必依赖 QuartzCore。
以下内容适用于任何 CGPathRef。在 UIBezierPath 的情况下,获取相同的 CGPath 属性:
- 在您要内省(introspection)的路径上使用
CGPathApply
以及自定义CGPathApplierFunction
函数。 - 将为该路径的每个组件调用您的
CGPathApplierFunction
。 CGPathElement(应用程序的参数)将告诉您它是什么类型的路径元素以及构成该元素的点(控制点或端点)。 kCGPathElementMoveToPoint
、kCGPathElementAddLineToPoint
、kCGPathElementAddQuadCurveToPoint
和kCGPathElementAddCurveToPoint
您将获得一、二、三和四点> 分别。- 将这些点存储在您选择的内部表示中。您只需为每个路径使用一次
CGPathApply
,这一步非常快。
现在,进入数学:
- 根据您希望找到位置的时间,比如说
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
现在的问题是,如何找出时间 t
的路径元素。您可以假设每个路径元素都有一个相等的时间片,或者您可以计算每个元素的距离并考虑小数时间(前一种方法对我来说效果很好)。另外,不要忘记为所有先前的路径元素添加时间(您不必为这些元素找到插值)。
正如我所说,这只是为了完整性(很可能是 Apple 自己解决这些问题的方式),并且前提是您愿意进行数学计算。
关于objective-c - 获取路径的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20622167/