Sine

   Sine, abbreviated sin, is a [1]trigonometric [2]function that simply said
   models a smooth oscillation, it is one of the most important and basic
   functions in geometry, [3]mathematics and [4]physics, and of course in
   [5]programming. Along with [6]cosine, [7]tangent and [8]cotangent it
   belongs to a group of functions that can be defined by ratios of sides of
   a right [9]triangle depending on one of the angles in it (hence
   trigonometric -- "triangle measuring"). If some measurement looks like
   sine function, we say it is harmonic. This is very common in nature and
   technology, e.g. a weight on a spring goes up and down by this function,
   [10]alternating current voltage has the sine shape (because it is
   generated by a circular motion), the amount of light falling onto a
   surface depends on the light angle via sine function etc.

   The function is most commonly defined using a right triangle as follows.
   Consider the following triangle:

           /|
          / |
         /  |
       c/   |
       /    |a
      /     |
     /     _|
    /A____|_|
        b

   Sin(A), where A is the angle between side b and c, is the ratio a / c. The
   function can be defined in many other ways, for example it is the curve we
   get when tracking only one direction (e.g. horizontal) of a point moving
   alongside circle (well, in the end it's actually related to the triangle
   definition) -- imagine something making a circular motion while casting a
   shadow onto a nearby wall (in a direction that's in the plane of
   rotation), the shadow will go up and down by sine of time. It can also be
   defined as a solution to some [11]differential equations etc.

   The graph of the sine function is following:

                   ^ sin(x)
                   |
                 1_|_
                   |     .--'''--.
       -1/2 pi     | _.''         ''._        3/2 pi
 .________|________.'________|________'|________|________.' --> x         
  '._     |     _.'|0        |         |'._     |     _.'|    
     ''--___--''  _|_      1/2 pi      pi  ''--___--''  2 pi
                -1 |

   Basically we'll observe a sine function in places where something
   oscillates naturally, gradually, i.e. where something goes there and back
   repeatedly but in a gradual, smooth manner, slowing down as it's
   approaching one end, coming to stop for a while, then reversing direction,
   slowly accelerating the other way and so on. Very rare in nature something
   comes there and back with constant speed, coming to stop and reversing
   directions instantly.

   Why the fuck are there these [12]pi values on the x line??? Nubs often
   can't comprehend this. These pi values are values in [13]radians, units of
   measuring angles where 2 pi is the full angle (360 degrees). In fact sine
   is sometimes shown with [14]degrees instead of radians (so imagine 90
   degrees on the line where there is 1/2 pi etc.), but mathematicians prefer
   radians. But why are there angles in the first place??? Why doesn't it go
   e.g. from 0 to 1 like all other nice functions? Well, it's because of the
   relation to geometry, remember the fucking triangle above... also if you
   define sine with a circle it all repeats after 2 pi. Just draw some
   picture if you don't get it.

   Some additional facts and properties regarding the sine functions are:

     * The domain are all [15]real numbers, the [16]codomain are real numbers
       in interval <-1,1> (including both bounds).
     * It is an [17]odd function (-sin(x) = sin(-x)).
     * It is periodic, with a period of 2 [18]pi.
     * Sine is just shifted [19]cosine, i.e. sin(x) = cos(x - 1/2 pi)
     * Its inverse function is [20]arcus sine, abbreviated asin, also written
       as sin^-1 -- this function tells you what argument you need to give to
       sin to get a specific result number. It's actually an inverse of only
       part of the sine function because the whole sine function can't be
       inverted, it isn't [21]bijective.
     * [22]Derivative of sin(x) is cos(x), the [23]integral of sin(x) dx is
       -cos(x).
     * By adding many differently shifted and scaled sine functions we can
       create basically any other function, see e.g. [24]cosine transform.
     * Sine and [25]cosine functions are used to draw [26]circles. If you
       plot points with x coordinate equal to sin(t) and y coordinate equal
       to cos(t) for t going from 0 to 2 * pi, you'll get a unit circle.
     * sin(x)^2 + cos(x)^2 = 1

   Some values of the sine function are:

   x (rad) x (deg) sin(x)             
   0       0       0                  
   pi / 12 15      ~0.259             
   pi / 6  30      0.5                
   pi / 4  45      sqrt(2)/2 ~= 0.707 
   pi / 3  60      sqrt(3)/2 ~= 0.866 
   pi / 2  90      1                  
   2 pi    360     0                  

Programming

   In programming languages the sine function is generally available in some
   math library, for example in [27]C the function sin is in math.h. Spare
   yourself bugs, always check if your sin function expects [28]radians or
   degrees!

   Want to make your own sine function for whatever reason (performance,
   curiosity, ...)? Then firstly consider what you expect from it. If you
   want a small, fast and perhaps integer only sin function (the one we'd
   prefer in [29]LRS) that doesn't need extreme accuracy, consider using a
   [30]look up table. You simply precompute the values of the sine function
   into a static table in memory and the function just retrieves them when
   called -- this is super fast. Note that you can save a lot of space by
   only storing sine values between 0 and 1/2 pi, the remaining parts of the
   function are just different transformations of this part. You can further
   save space and/or make the function work with [31]floats by further
   [32]interpolating (even just linearly) between the stored values, for
   example if sin(3.45) is called and you only have values stored for
   sin(3.4) and sin(3.5), you simply average them.

   Lot of times, e.g. in many calculators where speed isn't really critical,
   sine is computed using [33]Taylor series -- a sum of infinitely many terms
   of which if we take the first N, we get an [34]approximation of the
   function (the more terms we add, the more precise we get). For sine the
   series is

   sin(x) = x - x^3 / 3! + x^5 / 5! - x^7 / 7! + ...

   Adding just the first 3 terms (x - x^3 / 6 + x^5 / 120) already gives a
   very accurate approximation in range <-pi/2,pi/2> (error < 0.5 %). Here is
   a [35]C function that uses this to compute an 8bit sine (the magic numbers
   are made so as to incorporate pi while using power of two divisors, also
   note the use of many operations that will make the function relatively
   slow):

 // x = 255 means full angle, returns 0 to 255
 unsigned char sin8(unsigned char x)
 {
   int a = x;
   char flip = 0;

   if (a > 127)
   {
     a -= 128;
     flip = 1;
   }
  
   if (a > 63)
     a = 128 - a;

   int result = (411999 * a) - (a * a * a * 41);

   a /= 4;

   a = a * a * a * a * a;

   result = (a + result) / 131072;
   return flip ? (127 - result) : (127 + result);
 }

   If you just need a super fast and very rough sine-like value, there exists
   an ugly engineering approximation of sine that can be useful sometimes, it
   says that

   sin(x) = x, for small x

   Indeed, sine looks similar to a mere line near 0, but you can see it
   quickly diverges.

   Very rough and fast approximations e.g. for primitive music synthesis can
   be done with the traditional very basic [36]square or [37]triangle
   functions. The following is a simple 8bit linear approximation that's more
   accurate than square or triangle (approximates sine with a linear function
   in each octant):

 unsigned char sinA(unsigned char x)
 {
   unsigned char quadrant = x / 64;

   x %= 64;

   if (quadrant % 2 == 1)
     x = 63 - x;

   x = x < 32 ? (2 * x + x) : (64 + x);

   return quadrant <= 1 ? (128 + x) : (127 - x);
 }

   Similar approximation can be made with a quadratic curve, the following is
   a modification of the above function that does this (notice that now we
   need at least 16 bits for the computation so the data type changed to
   int): { I quickly made this just now, maybe it can be improved.
   ~drummyfish }

 int sinA(int x)
 {
   unsigned char quadrant = x / 64;

   x %= 64;

   if (quadrant % 2 == 1)
     x = 63 - x;

   x -= 63;
   x = (x * x) / 32;

   return quadrant <= 1 ? (255 - x) : x;
 }

   Sine can also be surprisingly accurately approximated with the
   [38]smoothstep function, which is just a polynomial 3 * x^2 - 2 * x^3.

   TODO: code for that

   Furthermore there exist other nice approximations, such as the extremely
   accurate Bhaskara I's approximation (angle in radians): sin(x) ~= (16 * x
   * (pi - x)) / (5 * pi^2 - 4 * x * (pi - x)). (This formula is actually
   more elegant for cosine, so it may be even better to consider using that.)
   Here is a [39]C [40]fixed point implementation:

 #define UNIT 1024
 #define PI ((int) (UNIT * 3.14159265))

 /* Integer sine using Bhaskara's approx. Returns a number
 in <-UNIT, UNIT> interval. Argument is in radians * UNIT. */

 int sinInt(int x) 
 {
   int sign = 1;
    
   if (x < 0) // odd function
   {
     x *= -1;
     sign = -1;
   }
    
   x %= 2 * PI;
  
   if (x > PI)
   {
     x -= PI;
     sign *= -1;
   }
    
   x *= PI - x;
  
   return sign * (16 * x) / ((5 * PI * PI - 4 * x) / UNIT);
 }

Links:
1. trigonometry.md
2. function.md
3. math.md
4. physics.md
5. programming.md
6. cos.md
7. tan.md
8. cot.md
9. triangle.md
10. ac.md
11. differential_equation.md
12. pi.md
13. radian.md
14. degree.md
15. real_number.md
16. codomain.md
17. odd_function.md
18. pi.md
19. cos.md
20. asin.md
21. bijection.md
22. derivative.md
23. integral.md
24. cosine_transform.md
25. cos.md
26. circle.md
27. c.md
28. radian.md
29. lrs.md
30. lut.md
31. float.md
32. interpolation.md
33. taylor_series.md
34. approximation.md
35. c.md
36. square_function.md
37. triangle_function.md
38. smoothstep.md
39. c.md
40. fixed_point.md