Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use better math constants #1447

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions API_CHANGES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# API breaking changes

## 0.55.2

- Usage of `M_PI`, `M_SQRT2` and `M_ROOT3` is deprecated, use constants from `common/Math/Constant.h` instead.
34 changes: 34 additions & 0 deletions src/common/Math.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <algorithm>

#include "math/Constant.h"

namespace Math {

// This is designed to return min if value is NaN. That's not guaranteed to work when
Expand Down Expand Up @@ -64,8 +66,40 @@ namespace Math {
volatile uint64_t bits = Util::bit_cast<uint64_t>(x);
return ~bits & 0x7ff0000000000000;
}

inline float DegToRad( float angle )
{
return angle * divpi_180_f;
}

inline float RadToDeg( float angle )
{
return angle * div180_pi_f;
}

inline double DegToRad( double angle )
{
return angle * divpi_180_d;
}

inline double RadToDeg( double angle )
{
return angle * div180_pi_d;
}
}

#include "math/Vector.h"

template<typename A>
DEPRECATED A DEG2RAD( const A a )
{
return Math::DegToRad( a );
}

template<typename A>
DEPRECATED A RAD2DEG( const A a )
{
return Math::RadToDeg ( a );
}

#endif //COMMON_MATH_H_
61 changes: 61 additions & 0 deletions src/common/math/Constant.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Generated with tools/math-constant/math-constant.py
// Do not modify!

#ifndef COMMON_MATH_CONSTANT_H_
#define COMMON_MATH_CONSTANT_H_

namespace Math {
// Type Name Value Operation GNU std::numbers
constexpr float phi_f = 1.61803399f; // φ phif
constexpr float egamma_f = 1.56746826f; // Γe egammaf
constexpr float ln2_f = .693147181f; // ln(2) M_LN2f ln2f
constexpr float ln10_f = 2.30258509f; // ln(10) M_LN10f ln10f
constexpr float log2e_f = 1.44269504f; // log2(e) M_LOG2Ef log2ef
constexpr float log10e_f = .434294482f; // log10(e) M_LOG10Ef log10ef
constexpr float pi_f = 3.14159265f; // π M_PIf pif
constexpr float mul2_pi_f = 6.28318531f; // 2π
constexpr float inv_pi_f = .318309886f; // 1÷π M_1_PIf inv_pif
constexpr float inv_mul2_pi_f = .159154943f; // 1÷2π
constexpr float div2_pi_f = .636619772f; // 2÷π M_2_PIf
constexpr float div180_pi_f = 57.2957795f; // 180÷π
constexpr float divpi_2_f = 1.57079633f; // π÷2 M_PI_2f
constexpr float divpi_4_f = .785398163f; // π÷4 M_PI_4f
constexpr float divpi_90_f = .034906585f; // π÷90
constexpr float divpi_180_f = .0174532925f; // π÷180
constexpr float divpi_360_f = .00872664626f; // π÷360
constexpr float sqrtpi_f = 1.77245385f; // √π sqrtpif
constexpr float sqrt2_f = 1.41421356f; // √2 M_SQRT2f sqrt2f
constexpr float sqrt3_f = 1.73205081f; // √3 sqrt3f
constexpr float inv_sqrtpi_f = 1.77245385f; // 1÷√π inv_sqrtpif
constexpr float inv_sqrt2_f = .707106781f; // 1÷√2 M_SQRT1_2f inv_sqrt2f
constexpr float inv_sqrt3_f = .577350269f; // 1÷√3 inv_sqrt3f
constexpr float div2_sqrtpi_f = 1.12837917f; // 2÷√π M_2_SQRTPIf

// Type Name Value Operation GNU std::numbers
constexpr double phi_d = 1.6180339887498948482; // φ phi
constexpr double egamma_d = 1.5674682557740530749; // Γe egamma
constexpr double ln2_d = .69314718055994530942; // ln(2) M_LN2 ln2
constexpr double ln10_d = 2.302585092994045684; // ln(10) M_LN10 ln10
constexpr double log2e_d = 1.4426950408889634074; // log2(e) M_LOG2E log2e
constexpr double log10e_d = .43429448190325182765; // log10(e) M_LOG10E log10e
constexpr double pi_d = 3.1415926535897932385; // π M_PI pi
constexpr double mul2_pi_d = 6.2831853071795864769; // 2π
constexpr double inv_pi_d = .31830988618379067154; // 1÷π M_1_PI inv_pi
constexpr double inv_mul2_pi_d = .15915494309189533577; // 1÷2π
constexpr double div2_pi_d = .63661977236758134308; // 2÷π M_2_PI
constexpr double div180_pi_d = 57.295779513082320877; // 180÷π
constexpr double divpi_2_d = 1.5707963267948966192; // π÷2 M_PI_2
constexpr double divpi_4_d = .78539816339744830962; // π÷4 M_PI_4
constexpr double divpi_90_d = .034906585039886591538; // π÷90
constexpr double divpi_180_d = .017453292519943295769; // π÷180
constexpr double divpi_360_d = .0087266462599716478846; // π÷360
constexpr double sqrtpi_d = 1.7724538509055160273; // √π sqrtpi
constexpr double sqrt2_d = 1.4142135623730950488; // √2 M_SQRT2 sqrt2
constexpr double sqrt3_d = 1.7320508075688772935; // √3 sqrt3
constexpr double inv_sqrtpi_d = 1.7724538509055160273; // 1÷√π inv_sqrtpi
constexpr double inv_sqrt2_d = .7071067811865475244; // 1÷√2 M_SQRT1_2 inv_sqrt2
constexpr double inv_sqrt3_d = .57735026918962576451; // 1÷√3 inv_sqrt3
constexpr double div2_sqrtpi_d = 1.1283791670955125739; // 2÷√π M_2_SQRTPI
}

#endif // COMMON_MATH_CONSTANT_H_
102 changes: 51 additions & 51 deletions src/engine/qcommon/q_math.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point,
float sind, cosd, expr;
vec3_t dxp;

degrees = DEG2RAD( degrees );
degrees = Math::DegToRad( degrees );
sind = sinf( degrees );
cosd = cosf( degrees );
expr = ( 1 - cosd ) * DotProduct( dir, point );
Expand Down Expand Up @@ -452,7 +452,7 @@ void vectoangles( const vec3_t value1, vec3_t angles )
{
if ( value1[ 0 ] )
{
yaw = RAD2DEG( atan2f( value1[ 1 ], value1[ 0 ] ) );
yaw = Math::RadToDeg( atan2f( value1[ 1 ], value1[ 0 ] ) );
}

else if ( value1[ 1 ] > 0 )
Expand All @@ -471,7 +471,7 @@ void vectoangles( const vec3_t value1, vec3_t angles )
}

forward = sqrtf( value1[ 0 ] * value1[ 0 ] + value1[ 1 ] * value1[ 1 ] );
pitch = RAD2DEG( atan2f( value1[ 2 ], forward ) );
pitch = Math::RadToDeg( atan2f( value1[ 2 ], forward ) );

if ( pitch < 0 )
{
Expand Down Expand Up @@ -705,7 +705,7 @@ float AngleBetweenVectors( const vec3_t a, const vec3_t b )
// this results in:
//
// angle = acos( (a * b) / (|a| * |b|) )
return RAD2DEG( acosf( DotProduct( a, b ) / ( alen * blen ) ) );
return Math::RadToDeg( acosf( DotProduct( a, b ) / ( alen * blen ) ) );
}

//============================================================
Expand Down Expand Up @@ -1011,15 +1011,15 @@ void AngleVectors( const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up

// static to help MS compiler fp bugs

angle = DEG2RAD( angles[ YAW ] );
angle = Math::DegToRad( angles[ YAW ] );
sy = sinf( angle );
cy = cosf( angle );

angle = DEG2RAD( angles[ PITCH ] );
angle = Math::DegToRad( angles[ PITCH ] );
sp = sinf( angle );
cp = cosf( angle );

angle = DEG2RAD( angles[ ROLL ] );
angle = Math::DegToRad( angles[ ROLL ] );
sr = sinf( angle );
cr = cosf( angle );

Expand Down Expand Up @@ -1355,7 +1355,7 @@ void AxisToAngles( /*const*/ vec3_t axis[ 3 ], vec3_t angles )
{
if ( axis[ 0 ][ 0 ] )
{
yaw = RAD2DEG( atan2f( axis[ 0 ][ 1 ], axis[ 0 ][ 0 ] ) );
yaw = Math::RadToDeg( atan2f( axis[ 0 ][ 1 ], axis[ 0 ][ 0 ] ) );
}

else if ( axis[ 0 ][ 1 ] > 0 )
Expand All @@ -1374,14 +1374,14 @@ void AxisToAngles( /*const*/ vec3_t axis[ 3 ], vec3_t angles )
}

length1 = sqrtf( axis[ 0 ][ 0 ] * axis[ 0 ][ 0 ] + axis[ 0 ][ 1 ] * axis[ 0 ][ 1 ] );
pitch = RAD2DEG( atan2f( axis[ 0 ][ 2 ], length1 ) );
pitch = Math::RadToDeg( atan2f( axis[ 0 ][ 2 ], length1 ) );

if ( pitch < 0 )
{
pitch += 360;
}

roll = RAD2DEG( atan2f( axis[ 1 ][ 2 ], axis[ 2 ][ 2 ] ) );
roll = Math::RadToDeg( atan2f( axis[ 1 ][ 2 ], axis[ 2 ][ 2 ] ) );

if ( roll < 0 )
{
Expand Down Expand Up @@ -1577,7 +1577,7 @@ bool MatrixInverse( matrix_t matrix )
}
void MatrixSetupXRotation( matrix_t m, vec_t degrees )
{
vec_t a = DEG2RAD( degrees );
vec_t a = Math::DegToRad( degrees );

m[ 0 ] = 1;
m[ 4 ] = 0;
Expand All @@ -1598,7 +1598,7 @@ void MatrixSetupXRotation( matrix_t m, vec_t degrees )
}
void MatrixSetupYRotation( matrix_t m, vec_t degrees )
{
vec_t a = DEG2RAD( degrees );
vec_t a = Math::DegToRad( degrees );

m[ 0 ] = cosf( a );
m[ 4 ] = 0;
Expand All @@ -1619,7 +1619,7 @@ void MatrixSetupYRotation( matrix_t m, vec_t degrees )
}
void MatrixSetupZRotation( matrix_t m, vec_t degrees )
{
vec_t a = DEG2RAD( degrees );
vec_t a = Math::DegToRad( degrees );

m[ 0 ] = cosf( a );
m[ 4 ] = -sinf( a );
Expand Down Expand Up @@ -1774,7 +1774,7 @@ void MatrixMultiplyRotation( matrix_t m, vec_t pitch, vec_t yaw, vec_t roll )
void MatrixMultiplyZRotation( matrix_t m, vec_t degrees )
{
matrix_t tmp;
float angle = DEG2RAD( degrees );
float angle = Math::DegToRad( degrees );
float s = sinf( angle );
float c = cosf( angle );

Expand Down Expand Up @@ -1857,15 +1857,15 @@ void MatrixToAngles( const matrix_t m, vec3_t angles )

if ( cp > 8192 * FLT_EPSILON )
{
angles[ PITCH ] = RAD2DEG( theta );
angles[ YAW ] = RAD2DEG( atan2f( m[ 1 ], m[ 0 ] ) );
angles[ ROLL ] = RAD2DEG( atan2f( m[ 6 ], m[ 10 ] ) );
angles[ PITCH ] = Math::RadToDeg( theta );
angles[ YAW ] = Math::RadToDeg( atan2f( m[ 1 ], m[ 0 ] ) );
angles[ ROLL ] = Math::RadToDeg( atan2f( m[ 6 ], m[ 10 ] ) );
}

else
{
angles[ PITCH ] = RAD2DEG( theta );
angles[ YAW ] = RAD2DEG( -atan2f( m[ 4 ], m[ 5 ] ) );
angles[ PITCH ] = Math::RadToDeg( theta );
angles[ YAW ] = Math::RadToDeg( -atan2f( m[ 4 ], m[ 5 ] ) );
angles[ ROLL ] = 0;
}

Expand All @@ -1878,16 +1878,16 @@ void MatrixToAngles( const matrix_t m, vec3_t angles )

if ( fabsf( ca ) > 0.005f ) // Gimbal lock?
{
angles[ PITCH ] = RAD2DEG( atan2f( m[ 6 ] / ca, m[ 10 ] / ca ) );
angles[ YAW ] = RAD2DEG( a );
angles[ ROLL ] = RAD2DEG( atan2f( m[ 1 ] / ca, m[ 0 ] / ca ) );
angles[ PITCH ] = Math::RadToDeg( atan2f( m[ 6 ] / ca, m[ 10 ] / ca ) );
angles[ YAW ] = Math::RadToDeg( a );
angles[ ROLL ] = Math::RadToDeg( atan2f( m[ 1 ] / ca, m[ 0 ] / ca ) );
}

else
{
// Gimbal lock has occurred
angles[ PITCH ] = RAD2DEG( atan2f( -m[ 9 ], m[ 5 ] ) );
angles[ YAW ] = RAD2DEG( a );
angles[ PITCH ] = Math::RadToDeg( atan2f( -m[ 9 ], m[ 5 ] ) );
angles[ YAW ] = Math::RadToDeg( a );
angles[ ROLL ] = 0;
}

Expand All @@ -1900,14 +1900,14 @@ void MatrixFromAngles( matrix_t m, vec_t pitch, vec_t yaw, vec_t roll )
static float sr, sp, sy, cr, cp, cy;

// static to help MS compiler fp bugs
sp = sinf( DEG2RAD( pitch ) );
cp = cosf( DEG2RAD( pitch ) );
sp = sinf( Math::DegToRad( pitch ) );
cp = cosf( Math::DegToRad( pitch ) );

sy = sinf( DEG2RAD( yaw ) );
cy = cosf( DEG2RAD( yaw ) );
sy = sinf( Math::DegToRad( yaw ) );
cy = cosf( Math::DegToRad( yaw ) );

sr = sinf( DEG2RAD( roll ) );
cr = cosf( DEG2RAD( roll ) );
sr = sinf( Math::DegToRad( roll ) );
cr = cosf( Math::DegToRad( roll ) );

m[ 0 ] = cp * cy;
m[ 4 ] = ( sr * sp * cy + cr * -sy );
Expand Down Expand Up @@ -2467,7 +2467,7 @@ void MatrixPerspectiveProjectionFovYAspectLH( matrix_t m, vec_t fov, vec_t aspec
{
vec_t width, height;

width = tanf( DEG2RAD( fov * 0.5f ) );
width = tanf( Math::DegToRad( fov * 0.5f ) );
height = width / aspect;

m[ 0 ] = 1 / width;
Expand All @@ -2491,8 +2491,8 @@ void MatrixPerspectiveProjectionFovXYLH( matrix_t m, vec_t fovX, vec_t fovY, vec
{
vec_t width, height;

width = tanf( DEG2RAD( fovX * 0.5f ) );
height = tanf( DEG2RAD( fovY * 0.5f ) );
width = tanf( Math::DegToRad( fovX * 0.5f ) );
height = tanf( Math::DegToRad( fovY * 0.5f ) );

m[ 0 ] = 1 / width;
m[ 4 ] = 0;
Expand All @@ -2516,8 +2516,8 @@ void MatrixPerspectiveProjectionFovXYRH( matrix_t m, vec_t fovX, vec_t fovY, vec
{
vec_t width, height;

width = tanf( DEG2RAD( fovX * 0.5f ) );
height = tanf( DEG2RAD( fovY * 0.5f ) );
width = tanf( Math::DegToRad( fovX * 0.5f ) );
height = tanf( Math::DegToRad( fovY * 0.5f ) );

m[ 0 ] = 1 / width;
m[ 4 ] = 0;
Expand All @@ -2542,8 +2542,8 @@ void MatrixPerspectiveProjectionFovXYInfiniteRH( matrix_t m, vec_t fovX, vec_t f
{
vec_t width, height;

width = tanf( DEG2RAD( fovX * 0.5f ) );
height = tanf( DEG2RAD( fovY * 0.5f ) );
width = tanf( Math::DegToRad( fovX * 0.5f ) );
height = tanf( Math::DegToRad( fovY * 0.5f ) );

m[ 0 ] = 1 / width;
m[ 4 ] = 0;
Expand Down Expand Up @@ -2839,14 +2839,14 @@ void QuatFromAngles( quat_t q, vec_t pitch, vec_t yaw, vec_t roll )
static float sr, sp, sy, cr, cp, cy;

// static to help MS compiler fp bugs
sp = sinf(DEG2RAD(pitch) * 0.5);
cp = cosf(DEG2RAD(pitch) * 0.5);
sp = sinf(Math::DegToRad(pitch) * 0.5);
cp = cosf(Math::DegToRad(pitch) * 0.5);

sy = sinf(DEG2RAD(yaw) * 0.5);
cy = cosf(DEG2RAD(yaw) * 0.5);
sy = sinf(Math::DegToRad(yaw) * 0.5);
cy = cosf(Math::DegToRad(yaw) * 0.5);

sr = sinf(DEG2RAD(roll) * 0.5);
cr = cosf(DEG2RAD(roll) * 0.5);
sr = sinf(Math::DegToRad(roll) * 0.5);
cr = cosf(Math::DegToRad(roll) * 0.5);

q[0] = sr * cp * cy - cr * sp * sy; // x
q[1] = cr * sp * cy + sr * cp * sy; // y
Expand Down Expand Up @@ -3011,29 +3011,29 @@ void QuatToAngles( const quat_t q, vec3_t angles )

if ( test > 0.4995 )
{
angles[YAW] = RAD2DEG(-2 * atan2f(q[0], q[3]));
angles[YAW] = Math::RadToDeg(-2 * atan2f(q[0], q[3]));
angles[PITCH] = 90;
angles[ROLL] = 0;
return;
}

if ( test < -0.4995 )
{
angles[YAW] = RAD2DEG(2 * atan2f(q[0], q[3]));
angles[YAW] = Math::RadToDeg(2 * atan2f(q[0], q[3]));
angles[PITCH] = -90;
angles[ROLL] = 0;
return;
}

// original for normalized quaternions:
// angles[PITCH] = RAD2DEG(asinf( 2.0f * (q[3] * q[1] - q[2] * q[0])));
// angles[YAW] = RAD2DEG(atan2f(2.0f * (q[3] * q[2] + q[0] * q[1]), 1.0f - 2.0f * (q2[1] + q2[2])));
// angles[ROLL] = RAD2DEG(atan2f(2.0f * (q[3] * q[0] + q[1] * q[2]), 1.0f - 2.0f * (q2[0] + q2[1])));
// angles[PITCH] = Math::RadToDeg(asinf( 2.0f * (q[3] * q[1] - q[2] * q[0])));
// angles[YAW] = Math::RadToDeg(atan2f(2.0f * (q[3] * q[2] + q[0] * q[1]), 1.0f - 2.0f * (q2[1] + q2[2])));
// angles[ROLL] = Math::RadToDeg(atan2f(2.0f * (q[3] * q[0] + q[1] * q[2]), 1.0f - 2.0f * (q2[0] + q2[1])));

// optimized to work with both normalized and unnormalized quaternions:
angles[PITCH] = RAD2DEG(asinf(2.0f * test));
angles[YAW] = RAD2DEG(atan2f(2.0f * (q[3] * q[2] + q[0] * q[1]), q2[0] - q2[1] - q2[2] + q2[3]));
angles[ROLL] = RAD2DEG(atan2f(2.0f * (q[3] * q[0] + q[1] * q[2]), -q2[0] - q2[1] + q2[2] + q2[3]));
angles[PITCH] = Math::RadToDeg(asinf(2.0f * test));
angles[YAW] = Math::RadToDeg(atan2f(2.0f * (q[3] * q[2] + q[0] * q[1]), q2[0] - q2[1] - q2[2] + q2[3]));
angles[ROLL] = Math::RadToDeg(atan2f(2.0f * (q[3] * q[0] + q[1] * q[2]), -q2[0] - q2[1] + q2[2] + q2[3]));
}

void QuatMultiply( const quat_t qa, const quat_t qb, quat_t qc )
Expand Down
Loading
Loading