所以你有一些任意值V,你知道 0 V Vmax。你想计算一个像素的 x 坐标,称之为X,你的“屏幕”的 x 坐标从 0 到Xmax。正如您所说,要以“正常”方式执行此操作,您会这样做
X = Xmax * V / Vmax
V = Vmax * X / Xmax
我喜欢这样想,我首先通过计算 V / Vmax 将值标准化为介于 0 和 1 之间,然后将此值乘以最大值以获得介于 0 和最大值之间的值。
要以对数方式执行相同操作,您需要为 V 值设置不同的下限。如果 V 永远 ValueError。所以假设 0 Vmin V Vmax。然后你需要找出什么要使用的对数,因为它们有无数个。三个是常见的,以 2、e 和 10 为底的,这导致 x 轴看起来像这样:
------|------|------|------|---- ------|------|------|------|----
2^-1 2^0 2^1 2^2 == 0.5 1 2 4
------|------|------|------|---- ------|------|------|------|----
e^-1 e^0 e^1 e^2 == 0.4 1 2.7 7.4
------|------|------|------|---- ------|------|------|------|----
10^-1 10^0 10^1 10^2 == 0.1 1 10 100
所以原则上,如果我们能从左边的表达式中得到指数,我们可以使用与上面相同的原理得到一个介于 0 和Xmax 之间的值,这当然是 log 的用武之地。假设您使用 base b,您可以使用这些表达式来回转换:
from math import log
logmax = log(Vmax / Vmin, b)
X = Xmax * log(V / Vmin, b) / logmax
V = Vmin * b ** (logmax * X / Xmax)
这几乎是相同的思维方式,只是你需要首先确保log(somevalue, b) 会给你一个非负值。您可以通过在log 函数中除以Vmin 来实现。现在你可以除以表达式可以产生的最大值,当然是log(Vmax / Vmin, b),你会得到一个介于0和1之间的值,和之前一样。
另一种方式,我们需要先归一化 (X / Xmax),然后再放大 (* logmax) 到反函数预期的最大值。顺便说一下,逆向是将b 提高到某个值。现在如果X 为0,b ** (logmax * X / Xmax) 将等于1,所以为了得到正确的下限,我们乘以Vmin。或者换一种说法,因为我们做的第一件事是除以Vmin,所以我们需要乘以Vmin,这是我们现在做的最后一件事。
要“缩放”等式的“右侧”,您需要做的就是切换等式,因此您从V 取幂到X,然后取对数。原则上是这样。因为您还必须对 X 可以为 0 的事实做一些事情:
logmax = log(Xmax + 1, b)
X = b ** (logmax * (V - Vmin) / (Vmax - Vmin)) - 1
V = (Vmax - Vmin) * log(X + 1, b) / logmax + Vmin