【发布时间】:2015-12-24 16:48:45
【问题描述】:
我正在尝试创建一个自定义动画,其动画曲线与使用 CAMediaTimingFunction (我在 OpenGL 中制作动画,因此无法使用它)具有相同的动画曲线。我也想远离UIKit,因为我希望它尽可能多平台。
CAMediaTimingFunction 使用三次 Bezier 函数从经过的时间计算动画进度。我不知道它是怎么做到的。
据我了解,三次贝塞尔函数是参数化定义的,当您尝试从中导出笛卡尔方程时,它会变得混乱。
明确一点:我想要一种方法,它接受 x 值输入并沿三次贝塞尔曲线返回 y 值输出。控制点将被限制在 (0, 0) 到 (1, 1) 之间。
我计划做的是使用以下函数中的参数方程为贝塞尔曲线生成一个点的轨迹(比如 100)两次 为每个点(一次用于 x,一次对于y),使用从0 到1 的t 的100 个值
static inline CGFloat bezierFunc1D(CGFloat t, CGFloat p0, CGFloat p1, CGFloat p2, CGFloat p3) {
return
(1-t)*(1-t)*(1-t) * p0
+ 3 * (1-t)*(1-t) * t * p1
+ 3 * (1-t) * t*t * p2
+ t*t*t * p3;
}
这是p0 到p3 的控制点,t 是从0 到1 的参数标量。我可以通过预先计算t 的平方和立方值来相当容易地优化它。
然后我打算使用线性插值来生成一个点数组,其中x 的值是线性分离的(例如x = 0.01, 0.02... 0.99),然后使用这个数组来定义我的动画进度。
这是解决这个问题的最佳方法吗?对于一个相当简单的任务来说,这似乎是一个相当密集的过程,尽管它可以在发布时预先计算。
我在this question 上看到回答者建议简单地消除x 并将函数定义为y 而不是t。 但是,这会给出非常不准确的结果,因为从 0.0 到 1.0 的线性贝塞尔曲线不会以线性方式动画。
有没有更有效的方法来解决这个问题?
有谁知道 Apple 如何在 CAMediaTimingFunction 中实现这一点,或者是否有一个库可以实现相同的结果?
或者有没有比使用三次贝塞尔函数更简单的替代方法,可以在动画的进出阶段提供平滑的动画曲线?
【问题讨论】:
-
听起来您的问题基本上是:“我如何对沿贝塞尔三次曲线等距分布的点进行采样?”查看stackoverflow.com/a/26131682/77567 和stackoverflow.com/a/17227585/77567 和stackoverflow.com/a/13667092/77567
-
这些问题的重点是使用
CGPath绘制贝塞尔曲线。如果我没有在问题中明确说明,我很抱歉,但我想尽可能远离 UIKit,因为我在 OpenGL 中这样做,并希望它像多平台一样可能的。而且它们实际上都没有帮助获得贝塞尔曲线的一组线性值(您无法从CGPath读取一组点,您只能沿着它进行渲染)。 -
如果你想要一个多平台的答案,你应该从你的标签中去掉
ios。顺便说一句,这些答案确实使用CGPathCreateCopyByDashingPath复制函数沿CGPath读取一组线性值。 -
哦,我看到使用
CGPathApply和CGPathCreateCopyByDashingPath.. 无论如何我想做的事情似乎很麻烦......所以谢谢,但不谢谢! -
我之前(现已删除)关于 Apple 如何做到这一点的评论不正确。 Here's Apple's code to sample a timing function, from WebKit.Example call here.
标签: c animation math bezier camediatiming