问题:三角/浮点问题
当使用math.h中的三角函数用一个简单的SDL 2.0.4应用程序(自顶向下移动/旋转未遂),我发现有一些轻微的错误三角函数的计算,导致'玩家'不能完全按照所面临的方向移动,这给我带来了很多困扰。我搜索了为什么会出现这种情况,主要原因似乎是浮点运算。
我使用了一个叫做libfixmath的定点数学库 - 并且问题解决了,但只是在某种程度上。以弧度返回的90度余弦为0.00775146,而不是0;然而,270度的余弦确实返回了0弧度!我必须承认这个问题让我陷入困境,我需要一些帮助(我的数学技能不是很好,这没有帮助)。
在定点算术中使用的变量:
double direction = 0.0;
double sinRadians = 0.0;
double cosRadians = 1.0; // presuming player starts facing direction of 0 degrees!
然后 '诠释主(INT的argc,字符* argv的[])' 涉及这些变量的部分:
if (keyDownW == true)
{
Player.setXPos(Player.getXPos() + (10 * sinRadians));
Player.setYPos(Player.getYPos() - (10 * cosRadians)); // +- = -
cout << "Cosine and Sine (in radians): " << cosRadians << ", " << sinRadians << endl;
cout << direction << " degrees \n" << endl;
}
else if (keyDownS == true)
{
Player.setXPos(Player.getXPos() - (6 * sinRadians));
Player.setYPos(Player.getYPos() + (6 * cosRadians)); // -- = +
}
if (keyDownA == true)
{
if (direction <= 0)
{
direction = 345;
}
else
{
direction -= 15;
}
direction = direction * (3.14159/180); // convert to radians
cosRadians = fix16_to_dbl(fix16_cos(fix16_from_dbl(direction)));
sinRadians = fix16_to_dbl(fix16_sin(fix16_from_dbl(direction)));
direction = direction * (180/3.14159); // convert back to degrees
}
else if (keyDownD == true)
{
if (direction >= 345)
{
direction = 0;
}
else
{
direction += 15;
}
direction = direction * (3.14159/180); // convert to radians
cosRadians = fix16_to_dbl(fix16_cos(fix16_from_dbl(direction)));
sinRadians = fix16_to_dbl(fix16_sin(fix16_from_dbl(direction)));
direction = direction * (180/3.14159); // convert back to degrees
}
当cosRadians和sinRadians被分配时,发生的是方向(已经从度数转换为弧度)被转换为一个定点数,然后用它来分别计算余弦和正弦,然后从一个定点数字回到分配的双重位置,所有与你se libfixmath库。
这里是目前的程序(编译为必要的.dll文件的.exe;我静态链接libfixmath库)所以你可以看到这个问题自己:https://mega.nz/#!iJggRbxY!ySbl-2X_oiJKFACyp_kLg9yuLcEsFM07lTRqLtKCsy4
任何想法,为什么发生这种情况?
将定点转换分解为单独的步骤并查看中间值。强烈怀疑这就是你会发现精度的降低。 – doug
为什么在弧度转换中这样粗略地逼近pi?与pi最接近的两倍是3.141592653589793 –
如果你只能移动NSEW,为什么你要使用float? – stark