所以我有以下角度(rad):3.45575213 现在我通过cos& amp转换它sin到一个向量(tDir之前为零):
tDir.x += cos(target->direction);
tDir.y += sin(target->direction);
现在我通过以下方式将其转换回来:
float newDir = Wrap2PI(atan2(tDir.y, tDir.x));
包装看起来像这样:
inline float Wrap2PI(float u)
{
while(u < 0)
u += PI2;
while (u >= PI2)
u -= PI2;
return u;
}
PI:
const float PI = 3.14159265359f;
const float PI2 = PI*2.0f;
结果有显着差异:3.45575237
当这个计算每秒执行120次,或者至少看起来像这样时,这种差异非常大,因为我的对象是顺时针旋转的,这是我在代码中找到的唯一不准确之处。有没有办法获得更好的结果?
编辑:发现问题!这不是不准确,矢量有时是0,0!我的坏!答案 0 :(得分:4)
如果您希望获得更高的准确度,则需要至少使用double
s,而不是float
s。
观察:
const float PI = 3.14159265359f;
printf("%0.15f\n", PI);
输出为3.141592741012573,表明该值仅精确存储到小数点后的6位数。这是float
数据类型的基本限制。
如果你使用double
,你会做得更好,long doubles
甚至更好。但是,在浮点数中重复应用超越函数永远不会完全解决,所以除非绝对必要,否则你应该避免转换。例如,坚持最方便的内部操作表示,只转换为I / O.
答案 1 :(得分:2)
float
为您提供6-7位精度。考虑使用double
。
无论如何,反复应用三角函数迟早会产生一些差异。
答案 2 :(得分:1)
从数值分析的角度来看,我发现您发布的程序产生0.00000024的错误并不奇怪。 C / C ++中的三角函数在内部使用迭代过程(例如,Newton-Raphson方法)来近似它们的结果。
但是,您可以通过将float
更改为double
或long double
而无需支付任何性能费用来提高准确性。然而,如果准确度是#1因子,您可以使用任意精度数学库,如:GMP。但是请注意,使用这种包装会对性能(即速度)产生影响。