出乎意料的是,我遇到了奇怪的问题:
这里是平凡线性拉格朗日插值的逻辑实现示例:
unsigned char mix(unsigned char x0, unsigned char x1, float position){
// LOGICALLY must be something like (real implementation should be
// with casts)...
return x0 + (x1 - x0) * position;
}
参数
x0
、x1
始终在 0 - 255 范围内。0.0f - 1.0f
范围内。
我真的尝试了大量的实现(使用不同的演员等),但它在我的情况下不起作用!它返回不正确的结果(看起来像变量溢出或类似的东西。在互联网上寻找解决方案整整一周后,我决定询问。可能有人遇到过类似的问题。
我使用的是MSVC 2017编译器(除了语言级别之外,大多数参数都是默认的)。
操作系统 - Windows 10x64,Little Endian。
我做错了什么以及问题的可能根源是什么?
更新: 看来这个问题比我想象的要深(感谢您的回复)。
这里是小型 github 项目的链接,它演示了我的问题: https://github.com/elRadiance/altitudeMapVisualiser
输出 bmp 文件应包含平滑的海拔图。相反,它包含垃圾。如果我只使用 x0 或 x1 作为插值函数的结果(没有插值),它就可以工作。没有它 - 不会(产生垃圾)。
运行它的主类:
#include "Visualiser.h"
int main() {
unsigned int width = 512;
unsigned int height = 512;
float* altitudes = new float[width * height];
float c;
for (int w = 0; w < width; w++) {
c = (2.0f * w / width) - 1.0f;
for (int h = 0; h < height; h++) {
altitudes[w*height + h] = c;
}
}
Visualiser::visualiseAltitudeMap("gggggggggg.bmp", width, height, altitudes);
delete(altitudes);
}
提前谢谢您!
已解决:谢天谢地@wololo。我的项目中的错误不在计算中。
我应该使用选项“二进制”打开文件:
file.open("test.bin", std::ios_base::out | std::ios_base::trunc | std::ios_base::binary);
如果没有它,数据中的某些点可以面对带有值的字节
10
Windows环境下可以像LineFeed一样处理,改为13
。
这是我相信的答案:
u8 lerp_uint8(u8 x, u8 y, u8 t) { return (((y - x) * t * 0x10101) + 0x800000 >> 24) + x; }