# cos(x) =?

Status
Not open for further replies.

#### alec_t

##### Well-Known Member
Once x is calculated the relationship with y still holds.

Last edited:

#### Ian Rogers

##### User Extraordinaire
Forum Supporter
For the time being, I've cranked up the micro speed to 32Mhz... It has allowed me to run with two trig functions.... I'll see if I can find an alternate sin ~ cosine routine... Currently 14mS to create an Arc... I need 6 of then so around 84mS is a tad too much, but! Hey ho!

#### JimB

##### Super Moderator
I have two functions in a piece of code..

x = cos(a);
y = sin(a);

When using degrees I normally just go.

x = cos(a);
y = 1 - x;
Ian, are you saying that sin(a) = 1 - cos(a) ?
I think that you are a bit off the mark there.

The correct relationship is sin^2 + cos^2 = 1

Which would give y = sqrt(1 - x^2) using your notation.

JimB

#### Ian Rogers

##### User Extraordinaire
Forum Supporter
Ian, are you saying that sin(a) = 1 - cos(a) ?
I think that you are a bit off the mark there.
Yep! Found that out in radians... sin(a) = cos(a + PI/2)... A tad crap for me...

I found a super duper fast routine here!!! But its only a small bit faster than XC8's builtin..

I thought that because cos(30) = 0.86 and sin(60) = 0.86, "Senior moment", it was linear back to front!!

What I do when I use cos for sin is.. cos (30) = sin(90-30) which is correct!! But using radians turned me upside down.

#### Ian Rogers

##### User Extraordinaire
Forum Supporter
I had a quick look through... Its in pascal for the x86 system... A couple of issues.. Namely A) its for 32 bit machine and B) it uses "fmul" and most PC's have a floating point unit... I would like to see how fast it runs turning of the hardware FPU and using the software FPU.

But for my PC ( Lazarus ) projects... Thanks for that!

#### MrAl

##### Well-Known Member
Hi,

Yes i had to look twice when i saw that 1-cos(a) was somehow coming out to sin(a)
And yes, rads=degrees*pi/180 so a formula like:
x=cos(a)

in degrees is just:
x=cos(a*pi/180)

The two best forms are probably these two:
x=r*cos(a)
y=r*sin(a)

combined with the circle of radius 'r':
r^2=x^2+y^2

and after substitution of x and y:
r^2=(r*cos(a))^2+(r*sin(a))^2
r^2=r^2*cos(a)^2+r^2*sin(a)^2
r^2=r^2*(cos(a)^2+sin(a)^2)
and using the identity cos(a)^2+sin(a)^2=1 we end up with:
r^2=r^2*1
so:
r^2=r^2

and we've proved the identity.

So we can solve for sin(a)^2 and get:
sin(a)^2=1-cos(a)^2

and taking the square root of both sides we get:
abs(sin(a))=sqrt(1-cos(a)^2)

and so we have to split this into two forms showing principle angles:
sin(a)=sqrt(1-cos(a)^2), for pi<=a<=0 (eg from a=0 to pi)
sin(a)=-sqrt(1-cos(a)^2), for -pi<=a<=0 (eg from a=0 to -pi)

Also note that sin(a) may be more accurate than using the calculation on some angles, especially those close to either 90 degrees or 0 degrees (one of the axes).

Last edited:

#### Ian Rogers

##### User Extraordinaire
Forum Supporter
So MrAl to answer my question

I have a point x,y.. I rotate the point around a central fixed point..
This means I need a vertical component ie... sin(x)
And a horizontal component namely cos(x)

I need to work out cos(x) without trig... Let me explain..

cos(20) = 0.9396... and sin(20) = 0.342... But! sin(90-20) = 0.9396... I "stupidly" assumed that I could use only one trig function.. BUT!! I soon realised that I cannot make the changes after the trig the alterations have to be made before the trig function... I just wondered if it were possible to only use 1 trig function for sin and cos

#### Ratchit

##### Well-Known Member
So MrAl to answer my question

I have a point x,y.. I rotate the point around a central fixed point..
This means I need a vertical component ie... sin(x)
And a horizontal component namely cos(x)

I need to work out cos(x) without trig... Let me explain..

cos(20) = 0.9396... and sin(20) = 0.342... But! sin(90-20) = 0.9396... I "stupidly" assumed that I could use only one trig function.. BUT!! I soon realised that I cannot make the changes after the trig the alterations have to be made before the trig function... I just wondered if it were possible to only use 1 trig function for sin and cos
Here you go, Cos{x} without trig once you know the single trig Sin[x]. To find the cosine after the sine is known, subtract from 1, the square of the sine, the extract the square root for the cosine as shown below.

t

Ratch

#### Attachments

• 14.5 KB Views: 50

#### MrAl

##### Well-Known Member
So MrAl to answer my question

I have a point x,y.. I rotate the point around a central fixed point..
This means I need a vertical component ie... sin(x)
And a horizontal component namely cos(x)

I need to work out cos(x) without trig... Let me explain..

cos(20) = 0.9396... and sin(20) = 0.342... But! sin(90-20) = 0.9396... I "stupidly" assumed that I could use only one trig function.. BUT!! I soon realised that I cannot make the changes after the trig the alterations have to be made before the trig function... I just wondered if it were possible to only use 1 trig function for sin and cos
Hi,

...and so we have to split this into two forms showing principle angles:
sin(a)=sqrt(1-cos(a)^2), for pi<=a<=0 (eg from a=0 to pi)
sin(a)=-sqrt(1-cos(a)^2), for -pi<=a<=0 (eg from a=0 to -pi)

Also note that sin(a) may be more accurate than using the calculation on some angles, especially those close to either 90 degrees or 0 degrees (one of the axes).
Hello again,

However, there are also the approxmations as sin(x) can be approximated in many ways.
For example sin(x) can be approximated one way as:
sin(x)=(5880*x-620*x^3)/(11*x^4+360*x^2+5880)

A simple 4 term Taylor series gets you there also:
sin(x)=x-x^3/6+x^5/120-x^7/5040

or:
cos(x)=1-x^2/2+x^4/24-x^6/720+x^8/40320

These are best between 0 and pi/2.

#### Ian Rogers

##### User Extraordinaire
Forum Supporter
I came across this.... As I am working on a small 128x128 screen it will do the job.

It comes from "Ye olde spectrum" but it is very fast...

I post it here for others... it only uses 45 point lookup.
C:
const char sintable[] ={
0,9,18,27,35,44,53,62,
70,79,87,96,104,112,120,127,
135,143,150,157,164,171,177,183,
190,195,201,206,211,216,221,225,
229,233,236,240,243,245,247,249,
251,253,254,254,255,255};

double mycos(double deg)
{
return mysin(90-deg);
}
double mysin(double deg)
{
int esti, diff;
while(deg>360)
deg-=360;
while(deg<0)
deg+=360;
if(deg>180)
{
deg-=180;
}
else
if(deg>90) deg = 180-deg;
deg/=2;
diff = (int)deg;
deg = deg - diff;
esti = sintable[diff];
diff = sintable[diff+1] - esti;
deg *= diff;
deg += esti;
}
Its at least 5 times faster than the math library!!

#### MrAl

##### Well-Known Member
Hi Ian,

Looks very interesting, i'll have to try it out a little later.

Maybe you could help me find an approximation i posted a while back for sin(x)?
I cant seem to find it now.
I posted on this site but not sure if it was in math or not now.

#### Ian Rogers

##### User Extraordinaire
Forum Supporter
Maybe you could help me find an approximation i posted a while back for sin(x)?
XC8 uses approximation, but for what I need its over the top... I am working to int precision so the above is overkill let alone the successive one ..

Here is XC8's sin()..
C:
double sin(double f)
{
const static double coeff_a[] =
{
207823.68416961012,
-76586.415638846949,
7064.1360814006881,
-237.85932457812158,
2.8078274176220686
};
const static double coeff_b[] =
{
132304.66650864931,
5651.6867953169177,
108.99981103712905,
1.0
};
double x2, y;
unsigned char sgn;
#ifdef i8086
if(_use8087)
return _sin87(f);
#endif
sgn = 0;
if(f < 0.0) {
f = -f;
sgn = 1;
}
f *= 1.0/TWO_PI;
f -= floor(f);
f *= 4.0;
if(f > 2.0) {
f -= 2.0;
sgn = !sgn;
}
if( f > 1.0)
f = 2.0 - f;
x2 = f * f;
y = eval_poly(x2, coeff_b, 3);
f *= eval_poly(x2, coeff_a, 4) / y;
if(sgn)
return -f;
return f;
}

double eval_poly(double x, const double * d, int n)
{
double res;
res = d[n];
while(n)
res = x * res + d[--n];
return res;
}
The eval_poly is the successive part..

#### Ratchit

##### Well-Known Member
Ian Rogers,
First of all, I would use a look-up table. It can be one degree increments from 0-90. Or, it can be 2 degree increments or more. The same 90° table can be used for the cos because cos(70) is sin(20). The same table can also be used for 0-360 be adjusting the sign of the sines. Once the angle is determined to the nearest degree, the incremental part can be determined. Then use the incremental Taylor series to calculate the sin of the total angle. Suppose we want to calculate the sin of 1.5 degrees. The integer degree part call "a" and the incremental part call "h". The incremental Taylor series is

Applying the above equation and converting a=1 degree and h=0.5 degree to radians, the sin of 1.5 degrees is easily found to be 0.0261769. Notice that successive derivatives of the sin alternate between the sin and cos. Fewer terms or a smaller look-up table can be used if lower precision is acceptable. Observe that the sin changes the fastest at 0 and pi radians, so the precision will be less at that area of the sin.

Ratch

Forum Supporter