Sinustable calculations by Azure |
Calculating sinus-tables can be quite useful in some cases - for example in 4k or 40k intros when you
are in a lack of diskspace and cant afford saving some extra kilobytes of tables. Also in other programs
some runtime-calculated sinus-tables might be useful. And last but not least programming a sinus-table generator
is a nice challange. This article covers the maths of some algorithms to calculate sinus-tables. No code is given. You should be able to implement it byself. Following methods are covered:
|
The Taylor-Series |
The Taylor series for the sinus-function, or in this special case a MacLaurin series, is quite easy to use.
Its a function. Everything you need to do is to insert the disired angle into the function f(x) and you get sin(x). Here we go:
f(x)=x - x^3/3! + x^5/5! -.... + x^(4k+1)/(4k+1)! - x^(4k+3)/(4k+3)!+... The more elements you add, the more accurate the approximation of sin(x) is getting. x^7 or x^9 is already quite accurate. Please note, that k!=1*2*3...k (faculty). 5!=1*2*3*4*5=120 for example. So just use this and your sinustable-generator will work fine: f(x)=x - x^3/6 + x^5/120 - x^7/5040 with x e [-pi;pi]
|
Extrapolation Using Trigonometrical Addition Theorems |
This algorithm is using a totally different approach. It is generating the sinus-table recursively out of the first
two values of the sinus-table and a given stepwidth. (well actually a cosinus - table in this case. But that is almost
the same). Trigonometric addition theorems:
1) cos(a+c) =cos(a)*cos(c) - sin(a)*sin(b) 2) forms into: 3) sin(a)*sin(b) =cos(a-c) - cos(a)*cos(c) inserting 3) into 1) gives the final equation: cos(a+c) =2*cos(a)*cos(c) - cos(a-c) This equation makes recursive sinustable calculation possible. how ? easy: f(x)=2*const*f(x-1) - f(x-2) So everything we need now are the first two values of the sinus (cosinus) list. f(0)=cos(0)=1 and f(1)=cos(c). Also the constant const is needed. It is const=cos(c)=f(1)."c" is the stepwidth of the sinus-list. With the usage of this algorithm really short sinustable generators are possible. But you have to take care of the accuracy. (14bit integer is NOT enough for a 1024 entry table)
|
The Harmonical Oscilator Approach |
This algorithm is also calculating the sinus-table recursively. But it is using a totally different approach, than the trigonometric
algorithm. The origins of this equations are to be found in the physic and differental algebra. They describe the energy balance of
a hormonical oscilator in a closed system. - Well I dont want to bore you with facts like that. Here is the derivation: Assumption: f(x+d)=f(x)+d*f'(x) with d>0 This isnt mathematically 100% correct, it is only an approximation. But still accurate enough for our purposes - and quite handy. Since we want to calculate sinus we set:f(x)=sin(x) d is the stepwidth of the sinus table we want to generate. sin(x+d)=sin(x)+d*cos(x) we derive the whole equation and multiply with d: d*cos(x+d)=d*cos(x)-d*d*sin(x)
1) sin(x+d) = sin(x) + d*cos(x) now we have got two equations, which complete each other to a recursive function to calculate sinus.
a' = a + b Fixed version: (read below)
a' = a + b
The starting value of a is: sin(0)=0
This algorithm seems to be a little bit easier to handle than the trigonometric one when it comes to integer
implementation. Well - the more accurate the calculations are , the later the function will degenerate.
|
Another Algebraic Approach |
This algorithm is very similar to the harmonical oscilator approach. But it has the advantage, that both sinus and cosinus
are calculated at the same time. Some people used it in the circlecompo. So I thought I should also add it here.. Assumption:
f(x+d)=f(x)+d*f'(x) Now we set: f(x)=sin(x) - thus f'(x)=cos(x) and f''(x)=-sin(x). Using this facts we can change the equations a bit.
f(x+d)=f(x)+d*f'(x) This gives us a nice recursive formula calculating both sin(x)=f(x) and cos(x)=f'(x):
a' = a + d * b Fixed version: (read below)
a' = a + d * b
The starting value of a is: sin(0)=0
|
Fix by Nao |
This is a little additional tweak to improve the accuracy of the last two approaches. Lets start :
a' = a + b*d
| 1 -d | = A
Let's say, in physic words, that this matrix don't keep 'energy' constant. In fact, area covered by rotation, increase, and we obtain a spiral instead a circle. Now, i rewrote A, with a little correction:
| 1 d | = A
a' = a + b*d
But, let try to substitute a' instead a in OLD b' formula:
b' = -d*a + b - b*d^2
a' = a + b*d
|