0

所以我有以下角度(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 !我的错!

4

3 回答 3

3

如果您想要比这更好的准确度,您需要至少使用doubles,而不是floats。

观察:

const float PI = 3.14159265359f;
printf("%0.15f\n", PI);

输出为 3.141592741012573,说明该值仅精确存储到小数点后 6 位。这是float数据类型的基本限制。

如果你使用doubles 你会做得更好,long doubles甚至更好。但是在浮点中重复应用超越函数永远不会完全正确,所以你应该避免转换,除非绝对必要。例如,坚持内部操作最方便的表示,只转换为 I/O。

于 2013-12-30T02:27:04.890 回答
1

float为您提供 6-7 位的精度。考虑使用double.

无论如何,反复应用三角函数迟早会产生一些差异。

于 2013-12-30T02:28:37.847 回答
1

从数值分析的角度来看,您发布的程序生成 0.00000024 的错误并不奇怪。C/C++ 中的三角函数在内部使用迭代过程(例如,Newton-Raphson 方法)来近似其结果。

但是,您可以通过更改floattodoublelong double不增加任何性能成本来提高准确性。不过,如果准确度是 #1 因素,您可以使用任意精度的数学库,例如:GMP。但是请注意,使用此类软件包会影响性能(即速度)。

于 2013-12-30T02:46:55.200 回答