三角精度损失

Loss of trig precision

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

#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 上的情况类似。

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";