Skip to content

Conversation

@ZvRzyan18
Copy link

@ZvRzyan18 ZvRzyan18 commented May 2, 2025

fix glm::fastTan, glm::fastAsin, glm::fastAcos, glm::fastAtan, They should work much better now across their domains.

Other changes

  • glm::wrapAngle, since fmod is slow so changed it into angle - trunc(angle / two_pi) * two_pi
  • glm::fastSin, glm::fastCos improve accuracy

Implementation

it uses different approximated polynomials to minimize the error

sin_poly(x) ~ (sin(sqrt(x))-sqrt(x)) / (x * sqrt(x))
sin(x) ~ x * x3 * sin_poly(x2)

cos_poly(x) ~ cos(sqrt(x))
cos(x) ~ cos_poly(x2)

asin_poly(x) ~ (asin(sqrt(x))-sqrt(x)) / (x * sqrt(x))
asin(x) ~ x * x3 * asin_poly(x2)

atan_poly(x) ~ (atan(sqrt(x))-sqrt(x)) / (x * sqrt(x))
atan(x) ~ x * x3 * atan_poly(x2)

Identity

Polynomial approximation is only accurate within its interval, so trig identity solves that

  • asin_poly(x) interval [0, 0.5]
    for x values [0.5, 1.0] asin(x) ~ pi/2 - 2 * asin_poly(sqrt((1 - x) / 2))
    for -x values asin(x) ~ -asin(abs(x))

  • tan(x)
    for +-x -> inf x values tan(x) ~ sin(x)/cos(x)

  • atan_poly(x) interval [0, 0.5]
    for x values [0.5, 1.0] atan(x) ~ atan_poly((x - 1) / (1 + x)) + pi/4
    for x values [1.0, inf] atan(x) ~ asin(x / sqrt(1 + x * x))
    alternative : atan(x) ~ pi/2 - atan(1 / x)
    for -x values atan(x) ~ -atan(abs(x))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant