Skip to content

Commit

Permalink
Store angles internally as radians
Browse files Browse the repository at this point in the history
  • Loading branch information
vittorioromeo committed May 6, 2024
1 parent ae269e1 commit 1171dce
Show file tree
Hide file tree
Showing 13 changed files with 121 additions and 105 deletions.
25 changes: 21 additions & 4 deletions include/SFML/System/Angle.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,26 +138,32 @@ class Angle
////////////////////////////////////////////////////////////
// NOLINTNEXTLINE(readability-identifier-naming)
static const Angle Zero; //!< Predefined 0 degree angle value
// NOLINTNEXTLINE(readability-identifier-naming)
static const Angle QuarterCircle; //!< Predefined 90 degree angle value
// NOLINTNEXTLINE(readability-identifier-naming)
static const Angle HalfCircle; //!< Predefined 180 degree angle value
// NOLINTNEXTLINE(readability-identifier-naming)
static const Angle FullCircle; //!< Predefined 360 degree angle value

private:
friend constexpr Angle degrees(float angle);
friend constexpr Angle radians(float angle);

////////////////////////////////////////////////////////////
/// \brief Construct from a number of degrees
/// \brief Construct from a number of radians
///
/// This function is internal. To construct angle values,
/// use sf::radians or sf::degrees instead.
///
/// \param degrees Angle in degrees
/// \param radians Angle in radians
///
////////////////////////////////////////////////////////////
constexpr explicit Angle(float degrees);
constexpr explicit Angle(float radians);

////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
float m_degrees{}; //!< Angle value stored as degrees
float m_radians{}; //!< Angle value stored as radians
};

////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -187,6 +193,7 @@ class Angle
////////////////////////////////////////////////////////////
/// \relates Angle
/// \brief Overload of == operator to compare two angle values
/// \note Does not automatically wrap the angle value
///
/// \param left Left operand (an angle)
/// \param right Right operand (an angle)
Expand All @@ -199,6 +206,7 @@ class Angle
////////////////////////////////////////////////////////////
/// \relates Angle
/// \brief Overload of != operator to compare two angle values
/// \note Does not automatically wrap the angle value
///
/// \param left Left operand (an angle)
/// \param right Right operand (an angle)
Expand All @@ -211,6 +219,7 @@ class Angle
////////////////////////////////////////////////////////////
/// \relates Angle
/// \brief Overload of < operator to compare two angle values
/// \note Does not automatically wrap the angle value
///
/// \param left Left operand (an angle)
/// \param right Right operand (an angle)
Expand All @@ -223,6 +232,7 @@ class Angle
////////////////////////////////////////////////////////////
/// \relates Angle
/// \brief Overload of > operator to compare two angle values
/// \note Does not automatically wrap the angle value
///
/// \param left Left operand (an angle)
/// \param right Right operand (an angle)
Expand All @@ -235,6 +245,7 @@ class Angle
////////////////////////////////////////////////////////////
/// \relates Angle
/// \brief Overload of <= operator to compare two angle values
/// \note Does not automatically wrap the angle value
///
/// \param left Left operand (an angle)
/// \param right Right operand (an angle)
Expand All @@ -247,6 +258,7 @@ class Angle
////////////////////////////////////////////////////////////
/// \relates Angle
/// \brief Overload of >= operator to compare two angle values
/// \note Does not automatically wrap the angle value
///
/// \param left Left operand (an angle)
/// \param right Right operand (an angle)
Expand Down Expand Up @@ -507,4 +519,9 @@ namespace Literals
/// sf::Angle a6 = 3.14_rad; // 3.14 radians
/// \endcode
///
/// Internally, sf::Angle stores the angle value as radians.
///
/// For the best performance and to minimize run-time conversions,
/// it is recommended to work with radians whenever possible.
///
////////////////////////////////////////////////////////////
63 changes: 32 additions & 31 deletions include/SFML/System/Angle.inl
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,14 @@ namespace sf
{
namespace priv
{
constexpr float pi = 3.141592654f;
constexpr float pi = 3.141592654f;
constexpr float tau = pi * 2.f;

constexpr float positiveRemainder(float a, float b)
{
assert(b > 0.0f && "Cannot calculate remainder with non-positive divisor");
assert(b > 0.f && "Cannot calculate remainder with non-positive divisor");
const float val = a - static_cast<float>(static_cast<int>(a / b)) * b;
if (val >= 0.f)
return val;
else
return val + b;
return val >= 0.f ? val : val + b;
}
} // namespace priv

Expand All @@ -55,104 +53,104 @@ constexpr Angle::Angle() = default;
////////////////////////////////////////////////////////////
constexpr float Angle::asDegrees() const
{
return m_degrees;
return m_radians * (180.f / priv::pi);
}


////////////////////////////////////////////////////////////
constexpr float Angle::asRadians() const
{
return m_degrees * (priv::pi / 180);
return m_radians;
}


////////////////////////////////////////////////////////////
constexpr Angle Angle::wrapSigned() const
{
return degrees(priv::positiveRemainder(m_degrees + 180, 360) - 180);
return radians(priv::positiveRemainder(m_radians + priv::pi, priv::tau) - priv::pi);
}


////////////////////////////////////////////////////////////
constexpr Angle Angle::wrapUnsigned() const
{
return degrees(priv::positiveRemainder(m_degrees, 360));
return radians(priv::positiveRemainder(m_radians, priv::tau));
}


////////////////////////////////////////////////////////////
constexpr Angle::Angle(float degrees) : m_degrees(degrees)
constexpr Angle::Angle(float radians) : m_radians(radians)
{
}


////////////////////////////////////////////////////////////
constexpr Angle degrees(float angle)
{
return Angle(angle);
return Angle(angle * (priv::pi / 180.f));
}


////////////////////////////////////////////////////////////
constexpr Angle radians(float angle)
{
return Angle(angle * (180 / priv::pi));
return Angle(angle);
}


////////////////////////////////////////////////////////////
constexpr bool operator==(Angle left, Angle right)
{
return left.asDegrees() == right.asDegrees();
return left.asRadians() == right.asRadians();
}


////////////////////////////////////////////////////////////
constexpr bool operator!=(Angle left, Angle right)
{
return left.asDegrees() != right.asDegrees();
return left.asRadians() != right.asRadians();
}


////////////////////////////////////////////////////////////
constexpr bool operator<(Angle left, Angle right)
{
return left.asDegrees() < right.asDegrees();
return left.asRadians() < right.asRadians();
}


////////////////////////////////////////////////////////////
constexpr bool operator>(Angle left, Angle right)
{
return left.asDegrees() > right.asDegrees();
return left.asRadians() > right.asRadians();
}


////////////////////////////////////////////////////////////
constexpr bool operator<=(Angle left, Angle right)
{
return left.asDegrees() <= right.asDegrees();
return left.asRadians() <= right.asRadians();
}


////////////////////////////////////////////////////////////
constexpr bool operator>=(Angle left, Angle right)
{
return left.asDegrees() >= right.asDegrees();
return left.asRadians() >= right.asRadians();
}


////////////////////////////////////////////////////////////
constexpr Angle operator-(Angle right)
{
return degrees(-right.asDegrees());
return radians(-right.asRadians());
}


////////////////////////////////////////////////////////////
constexpr Angle operator+(Angle left, Angle right)
{
return degrees(left.asDegrees() + right.asDegrees());
return radians(left.asRadians() + right.asRadians());
}


Expand All @@ -166,7 +164,7 @@ constexpr Angle& operator+=(Angle& left, Angle right)
////////////////////////////////////////////////////////////
constexpr Angle operator-(Angle left, Angle right)
{
return degrees(left.asDegrees() - right.asDegrees());
return radians(left.asRadians() - right.asRadians());
}


Expand All @@ -180,7 +178,7 @@ constexpr Angle& operator-=(Angle& left, Angle right)
////////////////////////////////////////////////////////////
constexpr Angle operator*(Angle left, float right)
{
return degrees(left.asDegrees() * right);
return radians(left.asRadians() * right);
}


Expand All @@ -201,39 +199,39 @@ constexpr Angle& operator*=(Angle& left, float right)
////////////////////////////////////////////////////////////
constexpr Angle operator/(Angle left, float right)
{
assert(right != 0 && "Angle::operator/ cannot divide by 0");
return degrees(left.asDegrees() / right);
assert(right != 0.f && "Angle::operator/ cannot divide by 0");
return radians(left.asRadians() / right);
}


////////////////////////////////////////////////////////////
constexpr Angle& operator/=(Angle& left, float right)
{
assert(right != 0 && "Angle::operator/= cannot divide by 0");
assert(right != 0.f && "Angle::operator/= cannot divide by 0");
return left = left / right;
}


////////////////////////////////////////////////////////////
constexpr float operator/(Angle left, Angle right)
{
assert(right.asDegrees() != 0 && "Angle::operator/ cannot divide by 0");
return left.asDegrees() / right.asDegrees();
assert(right.asRadians() != 0.f && "Angle::operator/ cannot divide by 0");
return left.asRadians() / right.asRadians();
}


////////////////////////////////////////////////////////////
constexpr Angle operator%(Angle left, Angle right)
{
assert(right.asDegrees() != 0 && "Angle::operator% cannot modulus by 0");
return degrees(priv::positiveRemainder(left.asDegrees(), right.asDegrees()));
assert(right.asRadians() != 0.f && "Angle::operator% cannot modulus by 0");
return radians(priv::positiveRemainder(left.asRadians(), right.asRadians()));
}


////////////////////////////////////////////////////////////
constexpr Angle& operator%=(Angle& left, Angle right)
{
assert(right.asDegrees() != 0 && "Angle::operator%= cannot modulus by 0");
assert(right.asRadians() != 0.f && "Angle::operator%= cannot modulus by 0");
return left = left % right;
}

Expand Down Expand Up @@ -277,5 +275,8 @@ constexpr Angle operator""_rad(unsigned long long angle)
// Note: the 'inline' keyword here is technically not required, but VS2019 fails
// to compile with a bogus "multiple definition" error if not explicitly used.
inline constexpr Angle Angle::Zero;
inline constexpr Angle Angle::QuarterCircle(radians(priv::pi / 2.f));
inline constexpr Angle Angle::HalfCircle(radians(priv::pi));
inline constexpr Angle Angle::FullCircle(radians(priv::tau));

} // namespace sf
4 changes: 2 additions & 2 deletions include/SFML/Window/Sensor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ namespace sf::Sensor
enum class Type
{
Accelerometer, //!< Measures the raw acceleration (m/s^2)
Gyroscope, //!< Measures the raw rotation rates (degrees/s)
Gyroscope, //!< Measures the raw rotation rates (radians/s)
Magnetometer, //!< Measures the ambient magnetic field (micro-teslas)
Gravity, //!< Measures the direction and intensity of gravity, independent of device acceleration (m/s^2)
UserAcceleration, //!< Measures the direction and intensity of device acceleration, independent of the gravity (m/s^2)
Orientation //!< Measures the absolute 3D orientation (degrees)
Orientation //!< Measures the absolute 3D orientation (radians)
};

// NOLINTNEXTLINE(readability-identifier-naming)
Expand Down
4 changes: 2 additions & 2 deletions src/SFML/Audio/AudioDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -304,8 +304,8 @@ void AudioDevice::setCone(const Listener::Cone& cone)

ma_engine_listener_set_cone(&*instance->m_engine,
0,
std::clamp(cone.innerAngle.asRadians(), 0.f, sf::degrees(360).asRadians()),
std::clamp(cone.outerAngle.asRadians(), 0.f, sf::degrees(360).asRadians()),
std::clamp(cone.innerAngle, sf::Angle::Zero, sf::Angle::FullCircle).asRadians(),
std::clamp(cone.outerAngle, sf::Angle::Zero, sf::Angle::FullCircle).asRadians(),
cone.outerGain);
}

Expand Down
2 changes: 1 addition & 1 deletion src/SFML/Audio/AudioDevice.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ class AudioDevice
sf::Vector3f position{0, 0, 0};
sf::Vector3f direction{0, 0, -1};
sf::Vector3f velocity{0, 0, 0};
Listener::Cone cone{sf::degrees(360), sf::degrees(360), 1};
Listener::Cone cone{sf::Angle::FullCircle, sf::Angle::FullCircle, 1};
sf::Vector3f upVector{0, 1, 0};
};

Expand Down
4 changes: 2 additions & 2 deletions src/SFML/Audio/MiniaudioUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ struct SavedSettings
float minGain{0.f};
float maxGain{1.f};
float rollOff{1.f};
float innerAngle{sf::degrees(360).asRadians()};
float outerAngle{sf::degrees(360).asRadians()};
float innerAngle{sf::Angle::FullCircle.asRadians()};
float outerAngle{sf::Angle::FullCircle.asRadians()};
float outerGain{0.f};
};

Expand Down
5 changes: 3 additions & 2 deletions src/SFML/Audio/SoundSource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include "SFML/System/Angle.hpp"
#include <SFML/Audio/SoundSource.hpp>

#include <miniaudio.h>
Expand Down Expand Up @@ -88,8 +89,8 @@ void SoundSource::setCone(const Cone& cone)
{
if (auto* sound = static_cast<ma_sound*>(getSound()))
ma_sound_set_cone(sound,
std::clamp(cone.innerAngle, sf::degrees(0), sf::degrees(360)).asRadians(),
std::clamp(cone.outerAngle, sf::degrees(0), sf::degrees(360)).asRadians(),
std::clamp(cone.innerAngle, sf::Angle::Zero, sf::Angle::FullCircle).asRadians(),
std::clamp(cone.outerAngle, sf::Angle::Zero, sf::Angle::FullCircle).asRadians(),
cone.outerGain);
}

Expand Down
4 changes: 3 additions & 1 deletion src/SFML/Graphics/CircleShape.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@ std::size_t CircleShape::getPointCount() const
////////////////////////////////////////////////////////////
Vector2f CircleShape::getPoint(std::size_t index) const
{
const Angle angle = static_cast<float>(index) / static_cast<float>(m_pointCount) * sf::degrees(360) - sf::degrees(90);
const Angle angle = static_cast<float>(index) / static_cast<float>(m_pointCount) * sf::Angle::FullCircle -
sf::Angle::QuarterCircle;

return Vector2f(m_radius, m_radius) + Vector2f(m_radius, angle);
}

Expand Down

0 comments on commit 1171dce

Please sign in to comment.