0

我在这里真的缺乏术语,所以对此有任何帮助。即使它没有回答问题,它也有望让我更接近答案。

我怎样才能从曲线y也是一个变量的函数中p得到(可能在 0 和 1 之间?或者最好的?)。

画得很糟糕的草图

我假设p它总是在 1 和 0 之间,就像输出一样y
图形只是一个插图,我不需要那个精确的曲线,而是接近这个想法的东西。

伪代码足以作为答案或 c 风格的东西(c、javascript 等)。

为了提供一点上下文,我有一个映射函数,其中一个参数可以是 - 我称之为 - 缓动函数。有基于penner方程的。因此,例如,如果我想做一个easeIn,我会提供:

 function (p) { return p * p; };

但我希望能够做图像中的事情:动态改变轻松度。具有如下功能:

function (p, curviness) { return /* something */; }
4

2 回答 2

2

您可以尝试使用Superellipse,它似乎具有您正在寻找的形状延展性。(特例:松鼠

更新

好的,所以超椭圆的方程如下:

abs(x/a)^n + abs(y/b)^n = 1

您将在两者的 [0,1] 范围内工作,因此我们可以丢弃绝对值。

a和分别代表椭圆的b长轴和短轴;我们将把它们设置为 1(这样超椭圆只能在任一方向上拉伸到 +/-1),并且只查看第一个象限(再次为 [0, 1])。

这给我们留下了:

x^n + y^n = 1

您希望您的最终功能看起来像:

y = f(p, n)

所以我们需要把事情变成那种形式(求解y)。

您对下一步做什么的最初想法是正确的(但变量已切换):

y^n = 1 - p^n

用你的变量p代替x.

现在,最初我想尝试使用 alog来隔离y,但这意味着我们必须采取log_y不会隔离它的双方。相反,我们可以取第 n 个根来取消n,从而隔离y

y = nthRoot(n, 1 - p^n)

如果这令人困惑,那么这可能会有所帮助:平方根只是提高到 的幂1/2,所以如果你取平方根,x你会有:

sqrt(x) == x^(1/2)

我们所做的是取 nth 根,这意味着我们将事物提升到1/n幂,这取消了nth 幂,y因为您将它们相乘:

(y^n)^(1/n) == y^(n * 1/n) == y^1 == y

因此我们可以把事情写成

y = (1 - p^n)^(1/n)

让事情看起来更好。

所以,现在我们有一个形式为

y = f(p, n)

但我们还没有完成:这个方程正在处理超椭圆第一象限中的值;这个象限的图表看起来与你想要的不同——你想要出现在第二象限的图表,只是移动了。

我们可以通过反转第一象限中的图表来纠正这个问题。我们将通过从 1 中减去它来做到这一点。因此,最终等式将是:

y = 1 - (1 - p^n)^(1/n)

根据我的 TI-83 的计算,它工作得很好。

注意:在维基百科的文章中,他们提到当n介于之间01然后曲线将向下/向内弯曲,当n等于时1你得到一条直线,当n大于1时它将被弯曲。但是,由于我们从 中减去东西1所以这种行为是相反的!(所以0thru1表示它已经退出,大于1表示它已经退出)。

你有它 - 我希望这就是你想要的:)

于 2013-07-12T20:11:18.523 回答
1

你的curviness属性是指数。

function(p, exp) { return Math.pow(p, exp); }
  • exp = 1给你直线
  • exp > 1给你指数线(底部两条)
  • 0 < exp < 1给你对数线(前两条)

要在上方和下方获得“匹配”曲线,an将在线性分界线上exp = 2匹配 an ,因此您可以定义一个“曲线”函数,使其更直观。exp = 1/2

function curvyInterpolator(p, curviness) {
    curviness = curviness > 0 ? curviness : 1/(-curviness);
    return Math.pow(p, curviness);
}
于 2013-07-12T20:12:06.383 回答