线性插值

转载于:二圈妹的知乎

线性插值

线性插值 linear interpolation

无需多言,公式:


P(t) = A + (B -A)t

P(t) = A(1-t) + Bt

这个函数一般我们叫做lerp.

template<typename T>
inline T lerp(const T &lo, const T &hi, float t)
{ return lo * (1 - t) + hi * t; }

如果门把t变成某个函数g(t),那么线性可以变得平滑,可以变成多项式等等...

双线性插值 bilinear interpolation


思路是类似的,我们首先用插值算出 nx0 和 nx1,然后再用插值算出P处的值:

nx0 = lerp(c00,c10,tx)

nx1 = lerp(c01,c11,tx)

p = lerp(nx0,nx1,ty)

如果我们展开的话长这样:

[公式]

三线性插值 Trilinear interpolation

同样的思路,只是我们推到3d空间:


a = lerp(c000,c100,tx)

b = lerp(c010,c110,tx)

c = lerp(c001,c101,tx)

d = lerp(c011,c111,tx)


得到了这四个点,再把它代入回双线性插值既可:


e = lerp(a, b, ty)

f = lerp(c, d, ty)


最终e, f之间构成了线性插值:


p = lerp(e,f,tz)

展开看各项的系数:

  • c000: (1-tx)(1-ty)(1-tz)
  • c100: tx(1-ty)(1-tz)
  • c010: (1-tx)ty(1-tz)
  • c110: txty(1-tz)
  • c001: (1-tx)(1-ty)tz
  • c101: tx(1-ty)tz
  • c011: (1-tx)tytz
  • c111: txtytz

如果写代码的话可以简单一点:

float accum = 0;
for (size_t i = 0; i < 2; i++)
    for (size_t j = 0; j < 2; j++)
        for (size_t k = 0; k < 2; k++)
            accum += (i*tx+(1-i)*(1-tx))*
                   (j*ty+(1-j)*(1-ty))*
                   (k*tz+(1-k)*(1-tz))*c[i][j][k];

例子

双线性插值的一个直观例子见题图:

生成图片代码

参考:

Scratchapixel - Interpolation

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值