所以我有以下的角度(rad):3.45575213现在我通过cos & 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!我的错!
发布于 2013-12-30 10:27:05
如果你想要更高的精确度,你至少需要使用doubles,而不是floats。
请注意:
const float PI = 3.14159265359f;
printf("%0.15f\n", PI);输出为3.141592741012573,这表明该值仅准确存储到小数点后的6位。这是float数据类型的一个基本限制。
如果你使用doubles,你会做得更好,long doubles甚至更好。但是在浮点数中重复应用超越函数永远不会准确地工作,所以除非绝对必要,否则您可能应该避免转换。例如,对于内部操作,坚持使用最方便的表示法,并且只对I/O进行转换。
发布于 2013-12-30 10:28:38
float给你6-7位的精度。考虑使用double。
无论如何,重复应用三角函数迟早会产生一些差异。
发布于 2013-12-30 10:46:55
从数值分析的角度来看,我并不奇怪你发布的过程产生了0.00000024的误差。C/C++中的三角函数在内部使用迭代过程(例如,牛顿-拉夫森方法)来近似其结果。
但是,您可以通过将float更改为double或long double来提高准确性,而不会对性能造成任何影响。然而,如果准确性是第一要素,你可以使用一个任意精度的数学库,比如:GMP。但是请注意,使用这样的包会影响性能(即速度)。
https://stackoverflow.com/questions/20832463
复制相似问题