1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

cos(x) =?

Discussion in 'Mathematics and Physics' started by Ian Rogers, Jun 27, 2017.

  1. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,251
    Likes:
    911
    Location:
    Rochdale UK
    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;

    When using radians...???
     
  2. alec_t

    alec_t Well-Known Member Most Helpful Member

    Joined:
    Jul 10, 2011
    Messages:
    9,289
    Likes:
    1,222
    Location:
    Cardiff, Wales
    Radians = degrees * pi/180.
    Once x is calculated the relationship with y still holds.
     
    Last edited: Jun 27, 2017
  3. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,251
    Likes:
    911
    Location:
    Rochdale UK
    Yes.. I know...

    I don't want to use two trig functions so I will deduce sin(x) from the answer of cos(x)..
     
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,251
    Likes:
    911
    Location:
    Rochdale UK

    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!
     
  6. JimB

    JimB Super Moderator Most Helpful Member

    Joined:
    Sep 11, 2004
    Messages:
    6,356
    Likes:
    586
    Location:
    Peterhead, Scotland
    ONLINE
    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
     
  7. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,251
    Likes:
    911
    Location:
    Rochdale UK
    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.
     
  8. Ratchit

    Ratchit Well-Known Member

    Joined:
    Mar 12, 2008
    Messages:
    1,948
    Likes:
    83
  9. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,251
    Likes:
    911
    Location:
    Rochdale UK
    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!
     
  10. MrAl

    MrAl Well-Known Member Most Helpful Member

    Joined:
    Sep 7, 2008
    Messages:
    11,042
    Likes:
    959
    Location:
    NJ
    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: Jul 3, 2017
  11. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,251
    Likes:
    911
    Location:
    Rochdale UK
    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
     
  12. Ratchit

    Ratchit Well-Known Member

    Joined:
    Mar 12, 2008
    Messages:
    1,948
    Likes:
    83
    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.

    Rogers.JPG t

    Ratch
     

    Attached Files:

  13. MrAl

    MrAl Well-Known Member Most Helpful Member

    Joined:
    Sep 7, 2008
    Messages:
    11,042
    Likes:
    959
    Location:
    NJ
    Hello again,

    As you can see i already answered that last question :)

    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.
     
  14. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,251
    Likes:
    911
    Location:
    Rochdale UK
    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.
    Code (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)
     {
     signed int quad;
     int esti, diff;
     while(deg>360)
      deg-=360;
     while(deg<0)
      deg+=360;
     if(deg>180)
      {
      quad= -1;
      deg-=180;
      }
     else
      quad = 1;
     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;
     return (deg/255)*quad;
     }
     
    Its at least 5 times faster than the math library!!
     
  15. MrAl

    MrAl Well-Known Member Most Helpful Member

    Joined:
    Sep 7, 2008
    Messages:
    11,042
    Likes:
    959
    Location:
    NJ
    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.
     
  16. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,251
    Likes:
    911
    Location:
    Rochdale UK
    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()..
    Code (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..
     
  17. Ratchit

    Ratchit Well-Known Member

    Joined:
    Mar 12, 2008
    Messages:
    1,948
    Likes:
    83
    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

    Rogers.JPG
    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
     
  18. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,251
    Likes:
    911
    Location:
    Rochdale UK
    Thanks Ratch, but like I said, precision isn't an issue.. I have reduce the sin from 34mS to just over 1mS.. Just perfect... As the largest radius possible is 64.. 255 is 4 times more than needed...
     

Share This Page