如何避免线性插值"trap"?

How to avoid "trap" with linear interpolation?

本文关键字:trap 插值 何避免 线性      更新时间:2023-10-16

i具有范围a(起始范围(和范围b(目标范围(,并且我需要将值aX从范围a缩放到范围b。代码是基本的线性插值:

double LinearInterpolation(double a0, double a1, double b0, double b1, double aX) {
    return b0 + (b1 - b0) * (aX - a0) / (a1 - a0);
}

事实是:范围B可以是1.0到1.0的0。但是,当我到达该范围时,我得到了一个"陷阱"的价值,无法返回。这是一个例子:

int main ()
{
    double a0 = 0.4;
    double a1 = 1.0;
    double b0 = 0.6;
    double b1 = 1.0;
    double aX = 0.58;
    aX = LinearInterpolation(a0, a1, b0, b1, aX);
    std::cout << aX << std::endl;
    b0 = 1.0;
    aX = LinearInterpolation(a0, a1, b0, b1, aX);
    std::cout << aX << std::endl;
    b0 = 0.6;
    aX = LinearInterpolation(a0, a1, b0, b1, aX);
    std::cout << aX << std::endl;    
}

直到b0为0,它将正确缩放aX值。当我到达b0 = b1 = 1.0时,我无法返回(aX总是1.0,因为X = a1,因此始终是b0 + (b1 - b0) => b1(。

如何避免这种情况?

如何避免这种情况?

不要存储实际值,而是在范围内的相对位置:

struct value_in_range {
  double normalized_offset;
  double in_range (double from, double to) const {
    return from + (to - from) * normalized_offset;
  }
};
value_in_range make_value_in_range (double from, double value, double to) {
  // Add assertions to avoid misuse
  return {(value - from) / (to - from)};
}

与您的示例:

int main ()
{
    double a0 = 0.4;
    double a1 = 1.0;
    double b0 = 0.6;
    double b1 = 1.0;
    double aX = 0.58;
    value_in_range X = make_value_in_range (a0, aX, a1);
    std::cout << X.in_range(b0, b1) << std::endl;
    b0 = 1.0;
    std::cout << X.in_range(b0, b1) << std::endl;
    b0 = 0.6;
    std::cout << X.in_range(b0, b1) << std::endl;
}

您也可以像原始代码一样设置aX