Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Approximating inverse trigonometric functions

I have to implement asin, acos and atan in environment where I have only following math tools:

  • sine
  • cosine
  • elementary fixed point arithmetic (floating point numbers are not available)

I also already have reasonably good square root function.

Can I use those to implement reasonably efficient inverse trigonometric functions?

I don't need too big precision (the floating point numbers have very limited precision anyways), basic approximation will do.

I'm already half decided to go with table lookup, but I would like to know if there is some neater option (that doesn't need several hundred lines of code just to implement basic math).

EDIT:

To clear things up: I need to run the function hundreds of times per frame at 35 frames per second.

like image 886
Matěj Zábský Avatar asked Sep 11 '11 12:09

Matěj Zábský


1 Answers

Submitting here my answer from this other similar question.

nVidia has some great resources I've used for my own uses, few examples: acos asin atan2 etc etc...

These algorithms produce precise enough results. Here's a straight up Python example with their code copy pasted in:

import math
def nVidia_acos(x):
    negate = float(x<0)
    x=abs(x)
    ret = -0.0187293
    ret = ret * x
    ret = ret + 0.0742610
    ret = ret * x
    ret = ret - 0.2121144
    ret = ret * x
    ret = ret + 1.5707288
    ret = ret * math.sqrt(1.0-x)
    ret = ret - 2 * negate * ret
    return negate * 3.14159265358979 + ret

And here are the results for comparison:

nVidia_acos(0.5)  result: 1.0471513828611643
math.acos(0.5)    result: 1.0471975511965976

That's pretty close! Multiply by 57.29577951 to get results in degrees, which is also from their "degrees" formula.

like image 133
Fnord Avatar answered Sep 20 '22 19:09

Fnord