問題:三角/浮點問題
當使用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