失去三角精度

时间:2017-03-10 20:38:10

标签: c++ precision trigonometry

对于重力模拟,我需要找到两个物体之间的角度,以便我可以施加力。但是,我正在失去精确度,我不知道在哪里。这是可以重现问题的最小代码。

#include<iostream>
using namespace std;

struct Vector2f
{
    float x, y;
};

Vector2f operator-(Vector2f& left, Vector2f& right)
{
    return Vector2f{ left.x - right.x, left.y - right.y };
}

double pi = 3.141592653589793238463;

double angle(Vector2f& one, Vector2f& two)
{
    Vector2f normal(one - two);

    if (!normal.x && !normal.y)
    {
        return 0.0f;
    }

    float theta = -(atan((double)(normal.y / normal.x)) - pi / 2);

    if (normal.x < 0)
    {
        return (theta - pi / 2);
    }
    else
    {
        return (theta + pi / 2);
    }

} 

int main()
{
    Vector2f one{ 0,0 };
    for (int i = -100; i <= 100; i += 100)
    {
        for (int j = -100; j <= 100; j += 100)
        {
            Vector2f two{ i,j };
            cout << i << ", " << j << endl;
            cout << "sin:\t" << sin(angle(one, two)) * 180.0f / pi << endl;
            cout << "cos:\t" << cos(angle(one, two)) * 180.0f / pi << endl;
            cout << endl;
        }
    }
    return 0;
}

例如,我应该得到45(由于网格比较(0,0)和(100,-100)),我得到的答案如40.5142和57.2958。我知道精度损失是否小于一度,但这很荒谬。我希望这段代码的所有输出都是45的倍数,基本上对于那些没有知识的人来说。将Vector2f的数据类型更改为double不会影响最终结果。你能帮我找到这个问题吗?

我正在使用VS 2015,但它在VS 2013上的情况类似。

1 个答案:

答案 0 :(得分:2)

sin(angle(one, two)) * 180.0f / pi没有意义。

应该是

sin(angle(one, two))

你可以打印你的角度

std::cout << angle(one, two)) * 180.0f / pi << " degree\n";
std::cout << angle(one, two)) << " radian\n";