如何将(lerp)范围输入线性插入到范围输出?

Phr*_*ogz 4 javascript algorithm linear-interpolation

我想在一系列输入值之间(例如,在 A 和 B 之间)进行一般性插值,并获得一系列输出值(例如,在 C 和 D 之间)。有时我想限制值(以便 B+10000 仍然输出 D),有时我不想。我该怎么做?

例如,输入速度在 20 mph 到 80 mph 之间,我想在 17 到 15 之间调整地图的缩放级别:

无夹紧

     | \ 
     |  \
 17  |   \
     |    \
     |     \
     |      \
     |       \
 15  |        \
     |         \
     +----------\-
        20  80   \
Run Code Online (Sandbox Code Playgroud)

带夹紧

     |
 17  |----
     |    \
     |     \
     |      \
     |       \
 15  |        ----
     |
     +------------
        20  80    
Run Code Online (Sandbox Code Playgroud)

我找到了这个实用函数,但是(a)它本身不支持钳位,需要第二个函数调用,并且(b)它只支持 0 和 1 之间的输入。

Phr*_*ogz 5

您想要的一般(未限制)方程是:

var unclamped = (x-minX) * (maxY-minY)/(maxX-minX) + minY;
Run Code Online (Sandbox Code Playgroud)

对于钳位,您可以在计算结果后钳位输出:

var clamped = Math.max( minY, Math.min( maxY, unclamped ) );
Run Code Online (Sandbox Code Playgroud)

或者您可以在使用之前钳制输入:

x = Math.max( minX, Math.min( maxX, x ) )
var clamped = (x-minX) * (maxY-minY)/(maxX-minX) + minY;
Run Code Online (Sandbox Code Playgroud)

如果线的斜率没有改变,并且您的夹紧愿望没有改变,您可以通过预先计算一次并生成适合您的输入和需求的函数来提高性能:

var unclamped = (x-minX) * (maxY-minY)/(maxX-minX) + minY;
Run Code Online (Sandbox Code Playgroud)

在行动:

var clamped = Math.max( minY, Math.min( maxY, unclamped ) );
Run Code Online (Sandbox Code Playgroud)
x = Math.max( minX, Math.min( maxX, x ) )
var clamped = (x-minX) * (maxY-minY)/(maxX-minX) + minY;
Run Code Online (Sandbox Code Playgroud)