温馨提示:本文翻译自stackoverflow.com,查看原文请点击:math - Derive an exponential value from a for loop's index
math

math - 从for循环的索引中得出指数值

发布于 2020-04-10 00:05:28

我有一组将在屏幕上进行动画处理的对象。我希望每个动画的随机延迟根据项目在集合中的位置逐渐增加。

目前,我可以像这样(Swift)一样轻松地线性完成此操作。

let proportionThroughContents = CGFloat(Double(idx) / Double(allNodes.count))
let delayRandomiserBaseValue: CGFloat = 40
let delayRandomiserGrowthValue: CGFloat = 60
let delayRandomiserValue = UInt32(delayRandomiserBaseValue + (delayRandomiserGrowthValue * proportionThroughContents))

我实际上想要一些数学函数来给我一点曲棍球棒般的效果,其中中间的项目仍具有较低的值,但最末端的项目仍具有较高的值。

这可能是一个数学问题,而不是编程问题,但是我觉得这很常见,足以保证它在这里。

查看更多

提问者
Ricky
被浏览
78
Salix alba 2020-02-01 18:48

有很多可能的选择。最简单的可能是二次方,如a x^2 + b x + c,其中x是您的比例,而a,b,c是适当的常数。在代码中,您需要将其编写为a*x*x + b*x + c

对于真正的指数函数,您需要k exp(l x)在代码中k * Math.exp(l*x)

选择常量比较棘手。要获得相同的二次方初始速率,只需选择b = delayRandomiserGrowthValuec = delayRandomiserBaseValue然后,您可以a根据延迟时间选择多长时间。a + b + c会给您最大的延迟。

let proportionThroughContents = CGFloat(Double(idx) / Double(allNodes.count))
let delayRandomiserBaseValue: CGFloat = 40           // c
let delayRandomiserGrowthValue: CGFloat = 60         // b
let delayRandomiserQuadraticValue: CGFloat = 60      // a
let delayRandomiserValue = UInt32(delayRandomiserBaseValue
       + delayRandomiserGrowthValue * proportionThroughContents 
       + delayRandomiserQuadraticValue * proportionThroughContents * proportionThroughContents  )

指数k是初始值,l*k是初始增长率。最后的延迟将是k e^l

let proportionThroughContents = CGFloat(Double(idx) / Double(allNodes.count))
let delayRandomiserBaseValue: CGFloat = 40           // k
let delayRandomiserGrowthValue: CGFloat = 60         // 
let l: CGFloat = delayRandomiserGrowthValue / delayRandomiserBaseValue  // l
let delayRandomiserValue = UInt32(delayRandomiserBaseValue * Math.exp(l*proportionThroughContents))

有了这些值l = 60/40 = 1.5,最大延迟将为40*exp(1.5) = 179