【问题标题】:coverting an angle to a vector and back changes the angle?将角度转换为矢量并返回会改变角度?
【发布时间】:2014-01-16 22:06:09
【问题描述】:

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

【问题讨论】:

  • float 只有 6-7 位有效的小数位精度。所以这个结果是意料之中的。
  • 对于 32 位 float,这并没有“显着不同”。

标签: c++ angle atan2


【解决方案1】:

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

观察:

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

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

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多