覆盖矢量的角度并返回会更改角度

coverting an angle to a vector and back changes the angle?

本文关键字:返回 覆盖      更新时间:2023-10-16

所以我有以下角度(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;
}

圆周率:

const float PI = 3.14159265359f;
const float PI2 = PI*2.0f;

结果明显不同:3.45575237

当每秒执行 120 次计算时,这种差异真的很大,或者至少看起来是这样,因为我的对象是顺时针旋转的,这是我设法在我的代码中发现的唯一不准确之处。有没有办法获得更好的结果?

编辑:发现问题了!这不是不准确,矢量有时是 0,0 !我的坏!

如果你想要比这更好的精度,你需要至少使用 double s,而不是 float s。

观察:

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

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

如果你使用double你会做得更好,long doubles甚至更好。 但是在浮点中重复应用超越函数无论如何都不会完全奏效,所以你应该避免转换,除非绝对必要。 例如,坚持使用最方便的内部操作表示形式,并且仅针对I/O进行转换。

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

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

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

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