我想优化我的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