#pragma once inline float M3D_ScalarSin(float Value) noexcept { // Map Value to y in [-pi,pi], x = 2*pi*quotient + remainder. float quotient = M3D_1DIV2PI * Value; if (Value >= 0.0f) quotient = static_cast(static_cast(quotient + 0.5f)); else quotient = static_cast(static_cast(quotient - 0.5f)); float y = Value - M3D_2PI * quotient; // Map y to [-pi/2,pi/2] with sin(y) = sin(Value). if (y > M3D_PIDIV2) y = M3D_PI - y; else if (y < -M3D_PIDIV2) y = -M3D_PI - y; // 11-degree minimax approximation float y2 = y * y; return (((((-2.3889859e-08f * y2 + 2.7525562e-06f) * y2 - 0.00019840874f) * y2 + 0.0083333310f) * y2 - 0.16666667f) * y2 + 1.0f) * y; } inline float M3D_ScalarSinEst(float Value) noexcept { // Map Value to y in [-pi,pi], x = 2*pi*quotient + remainder. float quotient = M3D_1DIV2PI * Value; if (Value >= 0.0f) quotient = static_cast(static_cast(quotient + 0.5f)); else quotient = static_cast(static_cast(quotient - 0.5f)); float y = Value - M3D_2PI * quotient; // Map y to [-pi/2,pi/2] with sin(y) = sin(Value). if (y > M3D_PIDIV2) y = M3D_PI - y; else if (y < -M3D_PIDIV2) y = -M3D_PI - y; // 7-degree minimax approximation float y2 = y * y; return (((-0.00018524670f * y2 + 0.0083139502f) * y2 - 0.16665852f) * y2 + 1.0f) * y; } inline float M3D_ScalarCos(float Value) noexcept { // Map Value to y in [-pi,pi], x = 2*pi*quotient + remainder. float quotient = M3D_1DIV2PI * Value; if (Value >= 0.0f) quotient = static_cast(static_cast(quotient + 0.5f)); else quotient = static_cast(static_cast(quotient - 0.5f)); float y = Value - M3D_2PI * quotient; // Map y to [-pi/2,pi/2] with cos(y) = sign*cos(x). float sign; if (y > M3D_PIDIV2) { y = M3D_PI - y; sign = -1.0f; } else if (y < -M3D_PIDIV2) { y = -M3D_PI - y; sign = -1.0f; } else { sign = +1.0f; } // 10-degree minimax approximation float y2 = y * y; float p = ((((-2.6051615e-07f * y2 + 2.4760495e-05f) * y2 - 0.0013888378f) * y2 + 0.041666638f) * y2 - 0.5f) * y2 + 1.0f; return sign * p; } inline float M3D_ScalarCosEst(float Value) noexcept { // Map Value to y in [-pi,pi], x = 2*pi*quotient + remainder. float quotient = M3D_1DIV2PI * Value; if (Value >= 0.0f) quotient = static_cast(static_cast(quotient + 0.5f)); else quotient = static_cast(static_cast(quotient - 0.5f)); float y = Value - M3D_2PI * quotient; // Map y to [-pi/2,pi/2] with cos(y) = sign*cos(x). float sign; if (y > M3D_PIDIV2) { y = M3D_PI - y; sign = -1.0f; } else if (y < -M3D_PIDIV2) { y = -M3D_PI - y; sign = -1.0f; } else { sign = +1.0f; } // 6-degree minimax approximation float y2 = y * y; float p = ((-0.0012712436f * y2 + 0.041493919f) * y2 - 0.49992746f) * y2 + 1.0f; return sign * p; } inline float M3D_ScalarASin(float Value) noexcept { // Clamp input to [-1,1]. bool nonnegative = (Value >= 0.0f); float x = std::fabs(Value); float omx = 1.0f - x; if (omx < 0.0f) omx = 0.0f; float root = std::sqrt(omx); // 7-degree minimax approximation float result = ((((((-0.0012624911f * x + 0.0066700901f) * x - 0.0170881256f) * x + 0.0308918810f) * x - 0.0501743046f) * x + 0.0889789874f) * x - 0.2145988016f) * x + 1.5707963050f; result *= root; // acos(|x|) // acos(x) = pi - acos(-x) when x < 0, asin(x) = pi/2 - acos(x) return (nonnegative ? M3D_PIDIV2 - result : result - M3D_PIDIV2); } inline float M3D_ScalarASinEst(float Value) noexcept { // Clamp input to [-1,1]. bool nonnegative = (Value >= 0.0f); float x = std::fabs(Value); float omx = 1.0f - x; if (omx < 0.0f) { omx = 0.0f; } float root = std::sqrt(omx); // 3-degree minimax approximation float result = ((-0.0187293f * x + 0.0742610f) * x - 0.2121144f) * x + 1.5707288f; result *= root; // acos(|x|) // acos(x) = pi - acos(-x) when x < 0, asin(x) = pi/2 - acos(x) return (nonnegative ? M3D_PIDIV2 - result : result - M3D_PIDIV2); } inline float M3D_ScalarACos(float Value) noexcept { // Clamp input to [-1,1]. bool nonnegative = (Value >= 0.0f); float x = std::fabs(Value); float omx = 1.0f - x; if (omx < 0.0f) omx = 0.0f; float root = std::sqrt(omx); // 7-degree minimax approximation float result = ((((((-0.0012624911f * x + 0.0066700901f) * x - 0.0170881256f) * x + 0.0308918810f) * x - 0.0501743046f) * x + 0.0889789874f) * x - 0.2145988016f) * x + 1.5707963050f; result *= root; // acos(x) = pi - acos(-x) when x < 0 return (nonnegative ? result : M3D_PI - result); } inline float M3D_ScalarACosEst(float Value) noexcept { // Clamp input to [-1,1]. bool nonnegative = (Value >= 0.0f); float x = std::fabs(Value); float omx = 1.0f - x; if (omx < 0.0f) omx = 0.0f; float root = std::sqrt(omx); // 3-degree minimax approximation float result = ((-0.0187293f * x + 0.0742610f) * x - 0.2121144f) * x + 1.5707288f; result *= root; // acos(x) = pi - acos(-x) when x < 0 return (nonnegative ? result : M3D_PI - result); }