mirror of
https://github.com/bkaradzic/bx.git
synced 2026-02-17 20:52:37 +01:00
Added bx::sinCosApprox.
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user