# Interpolation of sin/cos

I am trying to optimize sin/cos for my MCU in order to calculate geo distance. This part of formula particularly is using trigonometry:

double e = (MyTan( lat2 / 2 + quarter_pi ) / MyTan( lat1 / 2 + quarter_pi ));


So I tried to build my own sin/cos lookup tables for -PI to PI as follows:

#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);
}
}

{
int ix;
int sign = 1;

{
sign = -1;
}

ix = (rad * 180) / M_PI * PARTPERDEGREE;

return sign * mysinlut[ix];
}

{
int ix;
int sign = 1;

{
sign = -1;
}
else if(rad < -(M_PI / 2))
{
sign = -1;
}
else if(rad > -M_PI / 2 && rad < M_PI / 2)
{
sign = 1;
}

ix = (rad * 180) / M_PI * PARTPERDEGREE;

return sign * mycoslut[ix];
}

{
}


You can see the resolution of table is 10 parts per degree. I can increase it little, but it doesn't help much and it looks like I need some interpolation. Could anyone suggest some practical improvements to my functions to have better results? Below is graph of 234 different results of the e. Blue series are with ideal sin/cos and red are from LUT.

-
Have you had a look into CORDIC? –  Hagen von Eitzen Dec 6 '12 at 19:23
Yes, but the math is way too complex for me in order to implement. Haven't seen any simple implementation in C. –  Pablo Dec 6 '12 at 19:25

Good rational approximations for $\sin(x)$ and $\cos(x)$ on $[0, \pi/4]$ are

-.41498e-8+(1.000000515+(-.105463955e-4+(-.1665856017+(-.297181298e-3
+(.8894256955e-2-.5282205803e-3*x)*x)*x)*x)*x)*x


and

1.000000002+(-.2053e-6+(-.4999959817+(-.2922839e-4+(.4176577023e-1
+(-.163891331e-3-.1275240287e-2*x)*x)*x)*x)*x)*x


with maximum absolute errors approximately $.415 \times 10^{-8}$ and $.2 \times 10^{-8}$ respectively. You can use these to calculate $\sin(x)$ or $\cos(x)$ for any $x$: e.g. if $\pi/4 \le x \le \pi/2$ then $\sin(x) = \cos(\pi/2 - x)$ and $\cos(x) = \sin(\pi/2-x)$.

-