我想優化我的MCU的sin/cos以計算地理距離。公式的這一部分尤其是使用三角:如何改善正弦/餘弦函數?
double e = (MyTan(lat2/2 + quarter_pi)/MyTan(lat1/2 + quarter_pi));
所以我試圖建立自己的sin/cos
查找表-PI
到PI
如下:
#define PARTPERDEGREE 10
double mysinlut[PARTPERDEGREE * 90 + 1];
double mycoslut[PARTPERDEGREE * 90 + 1];
void MySinCosCreate()
{
int i;
double angle, angleinc;
// Each degree also divided into 10 parts
angleinc = (M_PI/180)/PARTPERDEGREE;
for (i = 0, angle = 0.0; i <= (PARTPERDEGREE * 90 + 1); ++i, angle += angleinc)
{
mysinlut[i] = sin(angle);
}
angleinc = (M_PI/180)/PARTPERDEGREE;
for (i = 0, angle = 0.0; i <= (PARTPERDEGREE * 90 + 1); ++i, angle += angleinc)
{
mycoslut[i] = cos(angle);
}
}
double MySin(double rad)
{
int ix;
int sign = 1;
if(rad > (M_PI/2))
rad = M_PI/2 - (rad - M_PI/2);
if(rad < -(M_PI/2))
rad = -M_PI/2 - (rad + M_PI/2);
if(rad < 0)
{
sign = -1;
rad *= -1;
}
ix = (rad * 180)/M_PI * PARTPERDEGREE;
return sign * mysinlut[ix];
}
double MyCos(double rad)
{
int ix;
int sign = 1;
if(rad > M_PI/2)
{
rad = M_PI/2 - (rad - M_PI/2);
sign = -1;
}
else if(rad < -(M_PI/2))
{
rad = M_PI/2 + (rad + M_PI/2);
sign = -1;
}
else if(rad > -M_PI/2 && rad < M_PI/2)
{
rad = abs(rad);
sign = 1;
}
ix = (rad * 180)/M_PI * PARTPERDEGREE;
return sign * mycoslut[ix];
}
double MyTan(double rad)
{
return MySin(rad)/MyCos(rad);
}
你可以看到表的分辨率爲10份每度。我可以增加一點,但它沒有多大幫助,看起來我需要一些插值。任何人都可以爲我的功能提出一些實際改進,以獲得更好的結以下是e
的234個不同結果的圖表。藍色系列具有理想的正弦/餘弦,紅色來自LUT。
你可以嘗試使用導數sin(x + h)〜sin x + h * cos x'來近似,這應該給出更好的結果。 –
@Daniel Fischer:你的意思是填充查找表嗎?你能否用一些小的僞代碼來回答,這會給我提示如何實現它? – Pablo