样条(分段三次多项式形式)可写为:
s = x - x[k]
y = y[k] + a[k]*s + b[k]*s*s + c[k]*s*s*s
其中x[k] < x < x[k+1]
,曲线通过每个(x[k], y[k])
点,a,b,c是描述斜率和形状的系数数组。这一切在浮点下工作正常,并且有很多方法可以计算不同类型样条曲线的a,b,c。然而...
如何以整数运算近似?
其中一个棘手的部分是,理想情况下,任何近似应该是连续的,换句话说,使用x=x[k+1]
和来自第k个分段的系数,除了舍入外,结果应为y[k+1]
错误。换句话说,对于直线段,y[k+1] == y[k] + a[k]*(x[k+1] - x[k])
和曲线段仅在中间偏离此而不是在任何一端。在浮点的情况下,这可以通过构造来保证,但即使从舍入的小系数变化也可以将其抛弃相当多。
另一个棘手的部分是,一般来说,高阶系数的幅度要小得多 - 但并非总是如此。不是在尖锐的“角落”。通过s的典型大小将它们扩展到它们的任何顺序的功率仍然是有意义的,因此它们不是作为整数舍入到零,但是这似乎会折衷曲率的分辨率以获得最大可能的角锐度
首先尝试整数版本:
y = y[k] + (a[k] + (b[k] + c[k]*s)*s)*s
然后使用整数乘法(用于16位值,32位算术):
#define q (1<<16)
#define mult(x, y) ((x * y) / q)
y = y[k] + mult(mult(mult(c[k], s) + b[k], s) + a[k], s)
这在理论上看起来不错,但我不确定这是最好的方法,或者如何系统地说出最好的方法是什么。