Math/Angle: Add sine, cosine, tangent methods
This commit is contained in:
parent
3cc70daf3e
commit
9e0b61f30d
|
|
@ -11,6 +11,7 @@
|
|||
#include <Nazara/Math/Algorithm.hpp>
|
||||
#include <Nazara/Math/Enums.hpp>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
|
|
@ -28,6 +29,11 @@ namespace Nz
|
|||
Angle(const Angle&) = default;
|
||||
~Angle() = default;
|
||||
|
||||
T GetCos() const;
|
||||
T GetSin() const;
|
||||
std::pair<T, T> GetSinCos() const;
|
||||
T GetTan() const;
|
||||
|
||||
Angle& MakeZero();
|
||||
|
||||
void Normalize();
|
||||
|
|
|
|||
|
|
@ -16,6 +16,11 @@ namespace Nz
|
|||
template<>
|
||||
struct AngleUtils<AngleUnit::Degree>
|
||||
{
|
||||
template<typename T> static constexpr T GetEpsilon()
|
||||
{
|
||||
return T(1e-4);
|
||||
}
|
||||
|
||||
template<typename T> static constexpr T GetLimit()
|
||||
{
|
||||
return 180;
|
||||
|
|
@ -55,9 +60,14 @@ namespace Nz
|
|||
template<>
|
||||
struct AngleUtils<AngleUnit::Radian>
|
||||
{
|
||||
template<typename T> static constexpr T GetEpsilon()
|
||||
{
|
||||
return T(1e-5);
|
||||
}
|
||||
|
||||
template<typename T> static constexpr T GetLimit()
|
||||
{
|
||||
return M_PI;
|
||||
return T(M_PI);
|
||||
}
|
||||
|
||||
template<typename T> static T FromDegrees(T degrees)
|
||||
|
|
@ -90,6 +100,14 @@ namespace Nz
|
|||
return out << "Angle(" << value << "rad)";
|
||||
}
|
||||
};
|
||||
|
||||
// Naive implementation, hopefully optimized by the compiler
|
||||
template<typename T>
|
||||
void SinCos(T x, T* sin, T* cos)
|
||||
{
|
||||
*sin = std::sin(x);
|
||||
*cos = std::cos(x);
|
||||
}
|
||||
}
|
||||
/*!
|
||||
* \ingroup math
|
||||
|
|
@ -108,6 +126,59 @@ namespace Nz
|
|||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Computes the cosine of the angle
|
||||
* \return Cosine of angle
|
||||
*
|
||||
* \see GetSinCos
|
||||
*/
|
||||
template<AngleUnit Unit, typename T>
|
||||
T Angle<Unit, T>::GetCos() const
|
||||
{
|
||||
return std::cos(ToRadians().angle);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Computes the sine of the angle
|
||||
* \return Sine of angle
|
||||
*
|
||||
* \see GetSinCos
|
||||
*/
|
||||
template<AngleUnit Unit, typename T>
|
||||
T Angle<Unit, T>::GetSin() const
|
||||
{
|
||||
return std::sin(ToRadians().angle);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Computes both sines and cosines of the angle
|
||||
* \return Sine and cosine of the angle
|
||||
*
|
||||
* \remark This is potentially faster than calling both GetSin and GetCos separately as it can computes both values at the same time.
|
||||
*
|
||||
* \see GetCos, GetSin
|
||||
*/
|
||||
template<AngleUnit Unit, typename T>
|
||||
std::pair<T, T> Angle<Unit, T>::GetSinCos() const
|
||||
{
|
||||
T sin, cos;
|
||||
Detail::SinCos<T>(ToRadians().angle, &sin, &cos);
|
||||
|
||||
return std::make_pair(sin, cos);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Computes the tangent of the angle
|
||||
* \return Tangent value of the angle
|
||||
*
|
||||
* \see GetCos, GetSin
|
||||
*/
|
||||
template<AngleUnit Unit, typename T>
|
||||
T Angle<Unit, T>::GetTan() const
|
||||
{
|
||||
return std::tan(ToRadians().angle);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Changes the angle value to zero
|
||||
*/
|
||||
|
|
@ -115,6 +186,7 @@ namespace Nz
|
|||
Angle<Unit, T>& Angle<Unit, T>::MakeZero()
|
||||
{
|
||||
angle = T(0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -303,7 +375,7 @@ namespace Nz
|
|||
template<AngleUnit Unit, typename T>
|
||||
bool Angle<Unit, T>::operator==(const Angle& Angle) const
|
||||
{
|
||||
return NumberEquals(angle, Angle.angle);
|
||||
return NumberEquals(angle, Angle.angle, Detail::AngleUtils<Unit>::GetEpsilon<T>());
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -315,7 +387,7 @@ namespace Nz
|
|||
template<AngleUnit Unit, typename T>
|
||||
bool Angle<Unit, T>::operator!=(const Angle& Angle) const
|
||||
{
|
||||
return !NumberEquals(angle, Angle.angle);
|
||||
return !NumberEquals(angle, Angle.angle, Detail::AngleUtils<Unit>::GetEpsilon<T>());
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
|
|||
|
|
@ -29,6 +29,26 @@ SCENARIO("Angle", "[MATH][ANGLE]")
|
|||
CHECK(angle.ToRadians() == expectedResult);
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We compute its sinus/cosinus separatly")
|
||||
{
|
||||
THEN("It should be equal to 1 and 0")
|
||||
{
|
||||
CHECK(angle.GetSin() == Approx(1.f).margin(0.0001f));
|
||||
CHECK(angle.GetCos() == Approx(0.f).margin(0.0001f));
|
||||
}
|
||||
|
||||
}
|
||||
AND_WHEN("We compute it at the same time")
|
||||
{
|
||||
auto sincos = angle.GetSinCos();
|
||||
|
||||
THEN("It should also be equal to 1 and 0")
|
||||
{
|
||||
CHECK(sincos.first == Approx(1.f).margin(0.0001f));
|
||||
CHECK(sincos.second == Approx(0.f).margin(0.0001f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GIVEN("A degree angle of 480deg")
|
||||
|
|
@ -48,9 +68,9 @@ SCENARIO("Angle", "[MATH][ANGLE]")
|
|||
}
|
||||
}
|
||||
|
||||
GIVEN("A degree angle of -270deg")
|
||||
GIVEN("A degree angle of -300deg")
|
||||
{
|
||||
Nz::DegreeAnglef angle(-270.f);
|
||||
Nz::DegreeAnglef angle(-300.f);
|
||||
|
||||
WHEN("We normalize it")
|
||||
{
|
||||
|
|
@ -58,7 +78,7 @@ SCENARIO("Angle", "[MATH][ANGLE]")
|
|||
|
||||
THEN("It should be equal to a normalized version of itself")
|
||||
{
|
||||
Nz::DegreeAnglef expectedResult(90.f);
|
||||
Nz::DegreeAnglef expectedResult(60.f);
|
||||
|
||||
CHECK(angle == expectedResult);
|
||||
}
|
||||
|
|
@ -91,7 +111,28 @@ SCENARIO("Angle", "[MATH][ANGLE]")
|
|||
CHECK(angle.ToDegrees() == expectedResult);
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We compute its sinus/cosinus separatly")
|
||||
{
|
||||
THEN("It should be equal to 0 and -1")
|
||||
{
|
||||
CHECK(angle.GetSin() == Approx(0.f).margin(0.0001f));
|
||||
CHECK(angle.GetCos() == Approx(-1.f).margin(0.0001f));
|
||||
}
|
||||
|
||||
}
|
||||
AND_WHEN("We compute it at the same time")
|
||||
{
|
||||
auto sincos = angle.GetSinCos();
|
||||
|
||||
THEN("It should also be equal to 0 and -1")
|
||||
{
|
||||
CHECK(sincos.first == Approx(0.f).margin(0.0001f));
|
||||
CHECK(sincos.second == Approx(-1.f).margin(0.0001f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GIVEN("A radian angle of 7pi")
|
||||
{
|
||||
Nz::RadianAnglef angle(float(7 * M_PI));
|
||||
|
|
|
|||
Loading…
Reference in New Issue