我需要一种比下面的方法更好的计算S曲线的方法。我使用它在drawRect方法中绘制S曲线,以及计算音乐文件音量的缓入/缓出以便淡化。
我之所以需要一种改进的方法是因为它在一个循环中被调用大约100次以计算曲线并且是高度CPU密集的。
我希望加速框架中的一个或几个矢量数学函数可能有所帮助,但我不知道从哪里开始。
3 * position * (1 - position) * (1 - position) * firstControlPoint + 3 *
position * position * (1 - position) * secondControlPoint +
position * position * position * 1.0;
其中firstControlPoint等于0.0,secondControlPoint等于1.0。
答案 0 :(得分:1)
您的S曲线是贝塞尔曲线,因此您可以使用De Casteljau's algorithm。
q0 = t * p0 + (1 - t) * p1
q1 = t * p1 + (1 - t) * p2
q2 = t * p2 + (1 - t) * p3
r0 = t * q0 + (1 - t) * q1
r1 = t * q1 + (1 - t) * q2
s0 = t * r0 + (1 - t) * r1
然后你可以使用SSE / AVX-intrinsics用一条指令流来计算多条曲线(2 - > 128位,4 - > 256位)。
答案 1 :(得分:1)
您可能对Even Faster Bézier上的这篇文章感兴趣,但对此的100次计算并不多。我在第一代iPad上每帧运行了数千次这样的计算。对于这么小的集合,you're unlikely to get much benefit from Accelerate(对于小数据集,Accelerate可能比简单C慢得多)。
但有几件事需要考虑:
如果控制点不变,您应该能够预先计算所有位置的值并将它们粘贴在表格中。这将大大提高性能。如果它们的变化频率低于您绘制的频率,则无论何时输入发生变化,仍然需要预先计算表格。此外,请确保您没有更频繁地计算这些值然后您实际需要它们(如果输入值可能快速变化,您可能需要等待输入结算然后重新计算任何内容)。
如果这是一台NEON设备(即iPhone或iPad),intrinsics are almost never a win(这可能会随着Clang变得更好而改变,但这是我在2012年的发现)。如果你真的需要性能,手工编码的NEON肯定是一个胜利,但编程是一个令人头痛的问题,所以我会先看看其他地方。汇编编程与C编程完全不同。如果你可以在特定点放下一个内在函数并使其更快,编译器就已经完成了(实际上它已经完成)。
如果您正在进行浮点数学运算,并且您只需要将结果“几乎完全正确并且非常适合绘图和动画”而不是“根据IEEE规则完全正确且可重现”,那么您应该转向快速数学。最简单的方法是将编译器优化从“最快,最小”转换为“最快,最具侵略性的优化”。很难想象这不是iOS应用程序的正确设置,而且几乎总是Mac应用程序的正确设置。此设置还会启用其他矢量化,这可能会对您的循环产生很大影响。
您一定要从WWDC 2013查看使用LLVM优化代码。它介绍了如何构建代码以让编译器为您提供最大程度的帮助。您可能还希望从相同的视频中查看“加速框架”,但Accelerate不太可能是解决此问题的正确工具。
不要自己计算,而应考虑使用带有自定义计时功能的CAPropertyAnimation
。这些可以用来设置任何值;不只是图层动画。要绘制曲线,请考虑使用UIBezierPath
而不是手动计算曲线。
有关实践中某些内容的示例,您可能会发现iOS推送限制中的CurvyText示例非常有用。它计算Bézier点及其斜率,以沿着移动曲线执行文本布局。