Implementing Cosine in C from Scratch (2020)
91–100 of 139 posts
Re: Implementing Cosine in C from Scratch (2020)
#92Mandatory Physics "troll" comment: For small angles, sin(x) ~= x and cos(x) ~= 1 -- the ["small angle approximation"]( https://en.wikipedia.org/wiki/Small-angle_approximation ) It's actually kind of ridiculous how many times it comes up and works well enough in undergraduate Mechanics.
Dont forget optics, there tan x=sin x
Re: Implementing Cosine in C from Scratch (2020)
#93Earlier quoted context omitted.
This a perfectly nice Programming 101 example of a recursive function -- if an angle is too large, calculate its sine using the sine of the half-angle, otherwise return the angle (or, if you're fancy, some simple polynomial approximation of the sine). I'm sure everyone did this in school (we did, in fact).
It's not obvious when you should switch over to an approximation (base case), so I'd say it's not a good example to introduce recursion. I have never seen it, and I did not do it in school.
"Relaxation" algorithms for calculating fields work that way.
Re: Implementing Cosine in C from Scratch (2020)
#94For instance, in a game, it's common to have a gun/spell or whatever that shoots enemies in a cone shape. Like a shotgun or burning hands. One way to code this is to calculate the angle between where you're pointing and the enemies, (using arccos) and if that angle is small enough, apply the damage or whatever.
A better way to do it to take the vector where the shotgun is pointing, and the vector to a candidate enemy is, and take the dot product of those two. Pre-compute the cosine of the angle of effect, and compare the dot product to that -- if the dot product is higher, it's a hit, if it's lower, it's a miss. (you can get away with very rough normalization in a game, for instance using the rqsrt instruction in sse2) You've taken a potentially slow arccos operation and turned it into a fast handful of basic float operations.
Or for instance, you're moving something in a circle over time. You might have something like
float angle = 0
for (...)
angle += 0.01
Instead, you might do: const float sin_dx = sin(0.01)
const float cos_dx = cos(0.01)
float sin_angle = 0
float cos_angle = 1
for (...)
const float new_sin_angle = sin_angle * cos_dx + cos_angle * sin_dx
cos_angle = cos_angle * cos_dx - sin_angle * sin_dx
sin_angle = new_sin_angle
And you've replaced a sin/cos pair with 6 elementary float operations.And there's the ever popular comparing squares of distances instead of comparing distances, saving yourself a square root.
In general, inner loops should never have a transcendental or exact square root in them. If you think you need it, there's almost always a way to hoist from an inner loop out into an outer loop.
Re: Implementing Cosine in C from Scratch (2020)
#95Earlier quoted context omitted.
This has been the standard algorithm used by every libm for decades. Its not special to Musl.
But isn't this code rarely called in practice? I guess on intel architectures the compiler just calls the fsin instruction of the cpu.
Re: Implementing Cosine in C from Scratch (2020)
#96This comes up in movement under constant rate of rotation as well as Fourier transforms. See [1] for details, but the basic idea uses the simple trig identities:
cos(theta + delta) = cos(theta) - (a*cos(theta) + b*sin(theta))
sin(theta + delta) = sin(theta) - (a*sin(theta) - b*cos(theta))
The values for a and b must be calculated, but only once if delta is constant: a = 2 sin^2(delta/2)
b = sin(delta)
By using these relationships, it is only necessary to calculate cos(theta) and sin(theta) once for the first term in the series in order to calculate the entire series (until accumulated errors become a problem).[1] Press, William H. et. al., Numerical Recipes, Third Edition, Cambridge University Press, p. 219
Re: Implementing Cosine in C from Scratch (2020)
#97Earlier quoted context omitted.
This a perfectly nice Programming 101 example of a recursive function -- if an angle is too large, calculate its sine using the sine of the half-angle, otherwise return the angle (or, if you're fancy, some simple polynomial approximation of the sine). I'm sure everyone did this in school (we did, in fact).
It's not obvious when you should switch over to an approximation (base case), so I'd say it's not a good example to introduce recursion. I have never seen it, and I did not do it in school.
Re: Implementing Cosine in C from Scratch (2020)
#98I think off-zero Taylor series along with lookup table should be at least tried. You can approximate cos(x+a) using only cos(a) and sin(a) and the series converges really fast
Re: Implementing Cosine in C from Scratch (2020)
#99This is a fun article! Alternative avenues that complement the approaches shown: - Padé Approximants ( https://en.wikipedia.org/wiki/Pad%C3%A9_approximant ) can be better than long Taylor Series for this kind of thing. - Bhaskara I's sin approximation ( https://en.wikipedia.org/wiki/Bhaskara_I%27s_sine_approximat... ) is easily adaptable to cosine, remarkably accurate for its simplicity and also fast to calculate.
Do you have any suggested reading?
Re: Implementing Cosine in C from Scratch (2020)
#100Earlier quoted context omitted.
This a perfectly nice Programming 101 example of a recursive function -- if an angle is too large, calculate its sine using the sine of the half-angle, otherwise return the angle (or, if you're fancy, some simple polynomial approximation of the sine). I'm sure everyone did this in school (we did, in fact).
It's not obvious when you should switch over to an approximation (base case), so I'd say it's not a good example to introduce recursion. I have never seen it, and I did not do it in school.