Added bx::sinCosApprox.

This commit is contained in:
Бранимир Караџић
2024-04-30 23:50:43 -07:00
parent 8372a4df3e
commit 74bda7e6cc
3 changed files with 51 additions and 0 deletions

View File

@@ -162,6 +162,20 @@ namespace bx
return _a * _a;
}
inline void sinCosApprox(float _a, float* _outSin, float* _outCos)
{
const float aa = _a - floor(_a/kPi2)*kPi2;
const float absA = abs(aa);
const float cosA = cos(absA);
const float cosASq = square(cosA);
const float tmp0 = sqrt(1.0f - cosASq);
const float tmp1 = aa > 0.0f && aa < kPi ? 1.0f : -1.0f;
const float sinA = mul(tmp0, tmp1);
*_outSin = sinA;
*_outCos = cosA;
}
inline BX_CONST_FUNC float sin(float _a)
{
return cos(_a - kPiHalf);

View File

@@ -203,6 +203,13 @@ namespace bx
///
BX_CONSTEXPR_FUNC float square(float _a);
/// Returns the both sine and cosine of the argument _a.
///
/// @remarks The function calculates cosine, and then approximates sine based on the cosine
/// result. Therefore calculation of sine is less accurate than calling `bx::sin` function.
///
void sinCosApprox(float _a, float* _outSin, float* _outCos);
/// Returns the sine of the argument _a.
///
BX_CONST_FUNC float sin(float _a);

View File

@@ -441,6 +441,36 @@ TEST_CASE("sin", "[math][libm]")
}
}
TEST_CASE("sinCos", "[math][libm]")
{
bx::WriterI* writer = bx::getNullOut();
bx::Error err;
for (float xx = -100.0f; xx < 100.0f; xx += 0.1f)
{
float ss, cc;
bx::sinCosApprox(xx, &ss, &cc);
bx::write(writer, &err, "sinCos(%f) == sin %f (expected: %f)\n", xx, ss, ::sinf(xx) );
bx::write(writer, &err, "sinCos(%f) == cos %f (expected: %f)\n", xx, cc, ::cosf(xx) );
REQUIRE(err.isOk() );
REQUIRE(bx::isEqual(ss, ::sinf(xx), 0.001f) );
REQUIRE(bx::isEqual(cc, ::cosf(xx), 0.00001f) );
}
for (float xx = -bx::kPi2; xx < bx::kPi2; xx += 0.0001f)
{
float ss, cc;
bx::sinCosApprox(xx, &ss, &cc);
bx::write(writer, &err, "sinCos(%f) == sin %f (expected: %f)\n", xx, ss, ::sinf(xx) );
bx::write(writer, &err, "sinCos(%f) == cos %f (expected: %f)\n", xx, cc, ::cosf(xx) );
REQUIRE(err.isOk() );
REQUIRE(bx::isEqual(ss, ::sinf(xx), 0.001f) );
REQUIRE(bx::isEqual(cc, ::cosf(xx), 0.00001f) );
}
}
TEST_CASE("sinh", "[math][libm]")
{
bx::WriterI* writer = bx::getNullOut();