3d中矢量旋转的简单实现会产生巨大的舍入误差,尤其是在执行不同轴周围的多次旋转时。 simple 1-axis example显示基本问题。我有一个代码,我在x轴和y轴周围旋转几次。在某些情况下,我在小数点后第二位出现错误(例如,向量的长度在旋转之前为1,之后为0.9)。我对相对错误< 1e-5
感到满意。
void Rotate_x(double data[3], double agl) {
agl *= M_PI/180.0;
double c = cos(agl); double s = sin(agl);
double tmp_y = c*data[1] - s*data[2];
double tmp_z = s*data[1] + c*data[2];
data[1] = tmp_y; data[2] = tmp_z;
}
是否有人可以指向一个库或某些代码,它可以绕坐标轴旋转点,但错误最小?
我发现的一切都是臃肿的线性代数库,对我来说是过度的。
修改:
我转到long double
精度和combined rotations来改善错误。对于双打,我并不完全满意(在最坏的情况下1e-3
相对错误)。这是最简单的解决方案,它可以正常工作。仍然不会介意一个很好的库,它可以准确地进行常规双精度旋转。
答案 0 :(得分:2)
更好的精度变量是不够的
如果您对同一数据应用了许多转换
[edit1]测试
original: (0.0000000000000000000,1.0000000000000000000,0.0000000000000000000)
rotated: (0.0000000000000000000,0.9999999999999998890,-0.0000000000000000273)
agl*=M_PI/180.0;
这是我的旋转看起来像
void Rotate(double *data,double agl)
{
agl*=M_PI/180.0;
double c = cos(agl); double s = sin(agl);
double tmp_y = c*data[1] - s*data[2];
double tmp_z = s*data[1] + c*data[2];
data[1] = tmp_y; data[2] = tmp_z;
}
[edit2] 32/64位比较
[double] //64bit floating point
(0.0000000000000000000,1.0000000000000000000,0.0000000000000000000)
(0.0000000000000000000,0.9999999999999998890,-0.0000000000000000273)
[float] //32bit floating point
(0.0000000000000000000,1.0000000000000000000,0.0000000000000000000)
(0.0000000000000000000,0.9999999403953552246,-0.0000000146747787255)