Browse Source

Math: group the free functions to make them easier to look up.

pull/342/head
Vladimír Vondruš 7 years ago
parent
commit
571ba7b17f
  1. 268
      src/Magnum/Math/Functions.h
  2. 9
      src/Magnum/Math/FunctionsBatch.h
  3. 10
      src/Magnum/Math/Packing.h

268
src/Magnum/Math/Functions.h

@ -58,38 +58,6 @@ namespace Implementation {
template<std::size_t size> struct IsBoolVectorOrScalar<BoolVector<size>>: std::true_type {};
}
/**
@brief Integral logarithm
Returns integral logarithm of given number with given base.
@see @ref log2(), @ref log(T)
*/
UnsignedInt MAGNUM_EXPORT log(UnsignedInt base, UnsignedInt number);
/**
@brief Base-2 integral logarithm
Returns integral logarithm of given number with base `2`.
@see @ref log(UnsignedInt, UnsignedInt), @ref log(T)
*/
UnsignedInt MAGNUM_EXPORT log2(UnsignedInt number);
/**
@brief Natural logarithm
Returns natural (base @f$ e @f$) logarithm of given number.
@see @ref Constants::e(), @ref log(UnsignedInt, UnsignedInt), @ref log2()
*/
template<class T> inline T log(T number) { return std::log(number); }
/**
@brief Natural exponential
Returns @f$ e^x @f$.
@see @ref Constants::e(), @ref pow(T, T)
*/
template<class T> inline T exp(T exponent) { return std::exp(exponent); }
/**
@brief Integer division with remainder
@ -109,39 +77,13 @@ template<class Integral> inline std::pair<Integral, Integral> div(Integral x, In
}
/**
@brief If given number is a positive or negative infinity
@{ @name Trigonometric functions
@see @ref isNan(), @ref Constants::inf()
Unlike @ref std::sin() and friends, those take or return strongly-typed units
to prevent degrees being accidentally interpreted as radians and such. See
@ref Magnum::Math::Deg "Deg" and @ref Magnum::Math::Rad "Rad" for more
information.
*/
template<class T> inline typename std::enable_if<IsScalar<T>::value, bool>::type isInf(T value) {
return std::isinf(UnderlyingTypeOf<T>(value));
}
/** @overload */
template<std::size_t size, class T> inline BoolVector<size> isInf(const Vector<size, T>& value) {
BoolVector<size> out;
for(std::size_t i = 0; i != size; ++i)
out.set(i, Math::isInf(value[i]));
return out;
}
/**
@brief If given number is a NaN
Equivalent to @cpp value != value @ce.
@see @ref isInf(), @ref Constants::nan()
*/
template<class T> inline typename std::enable_if<IsScalar<T>::value, bool>::type isNan(T value) {
return std::isnan(UnderlyingTypeOf<T>(value));
}
/** @overload */
template<std::size_t size, class T> inline BoolVector<size> isNan(const Vector<size, T>& value) {
BoolVector<size> out;
for(std::size_t i = 0; i != size; ++i)
out.set(i, Math::isNan(value[i]));
return out;
}
/** @todo Can't trigonometric functions be done with only one overload? */
@ -204,58 +146,56 @@ template<class T> inline Rad<T> acos(T value) { return Rad<T>(std::acos(value));
/** @brief Arc tangent */
template<class T> inline Rad<T> atan(T value) { return Rad<T>(std::atan(value)); }
/*@}*/
/**
@{ @name Scalar/vector functions
These functions are overloaded for both scalar and vector types, including
@ref Deg and @ref Rad. Scalar versions function exactly as their possible STL
equivalents, vector overloads perform the operations component-wise.
@ref Magnum::Math::Deg "Deg" and @ref Magnum::Math::Rad "Rad". Scalar versions
function exactly as their possible STL equivalents, vector overloads perform
the operations component-wise.
*/
/**
@brief Integral power
@brief If given number is a positive or negative infinity
Returns integral power of base to the exponent. Works only on types that
satisfy @ref IsUnitless.
@see @ref pow(T, T)
@see @ref isNan(), @ref Constants::inf()
*/
template<UnsignedInt exponent, class T> constexpr typename std::enable_if<IsScalar<T>::value, T>::type pow(T base) {
static_assert(IsUnitless<T>::value, "expected an unitless type");
return Implementation::Pow<exponent>::pow(base);
template<class T> inline typename std::enable_if<IsScalar<T>::value, bool>::type isInf(T value) {
return std::isinf(UnderlyingTypeOf<T>(value));
}
/** @overload */
template<UnsignedInt exponent, std::size_t size, class T> inline Vector<size, T> pow(const Vector<size, T>& base) {
Vector<size, T> out{NoInit};
template<std::size_t size, class T> inline BoolVector<size> isInf(const Vector<size, T>& value) {
BoolVector<size> out;
for(std::size_t i = 0; i != size; ++i)
out[i] = Math::pow<exponent>(base[i]);
out.set(i, Math::isInf(value[i]));
return out;
}
/**
@brief Power
@brief If given number is a NaN
Returns power of @p base to the @p exponent. Works only on types that satisfy
@ref IsUnitless.
@see @ref pow(T), @ref exp()
Equivalent to @cpp value != value @ce.
@see @ref isInf(), @ref Constants::nan()
*/
template<class T> inline typename std::enable_if<IsScalar<T>::value, T>::type pow(T base, T exponent) {
static_assert(IsUnitless<T>::value, "expected an unitless type");
return std::pow(base, exponent);
template<class T> inline typename std::enable_if<IsScalar<T>::value, bool>::type isNan(T value) {
return std::isnan(UnderlyingTypeOf<T>(value));
}
/** @overload */
template<std::size_t size, class T> inline Vector<size, T> pow(const Vector<size, T>& base, T exponent) {
Vector<size, T> out{NoInit};
template<std::size_t size, class T> inline BoolVector<size> isNan(const Vector<size, T>& value) {
BoolVector<size> out;
for(std::size_t i = 0; i != size; ++i)
out[i] = Math::pow(base[i], exponent);
out.set(i, Math::isNan(value[i]));
return out;
}
/**
@brief Minimum
<em>NaN</em>s passed in @p value parameter are propagated.
<em>NaN</em>s passed in the @p value parameter are propagated.
@see @ref max(), @ref minmax(), @ref clamp(),
@ref min(Corrade::Containers::ArrayView<const T>), @ref Vector::min()
*/
@ -281,7 +221,7 @@ template<std::size_t size, class T> inline Vector<size, T> min(const Vector<size
/**
@brief Maximum
<em>NaN</em>s passed in @p value parameter are propagated.
<em>NaN</em>s passed in the @p value parameter are propagated.
@see @ref min(), @ref minmax(), @ref clamp(),
@ref max(Corrade::Containers::ArrayView<const T>), @ref Vector::max()
*/
@ -426,42 +366,6 @@ template<std::size_t size, class T> inline Vector<size, T> ceil(const Vector<siz
return out;
}
/**
@brief Square root
Works only on types that satisfy @ref IsUnitless.
@see @ref sqrtInverted(), @ref Vector::length(), @ref sqrt(const Dual<T>&)
*/
template<class T> inline typename std::enable_if<IsScalar<T>::value, T>::type sqrt(T a) {
static_assert(IsUnitless<T>::value, "expecting an unitless type");
return std::sqrt(a);
}
/** @overload */
template<std::size_t size, class T> inline Vector<size, T> sqrt(const Vector<size, T>& a) {
Vector<size, T> out{NoInit};
for(std::size_t i = 0; i != size; ++i)
out[i] = Math::sqrt(a[i]);
return out;
}
/**
@brief Inverse square root
Works only on types that satisfy @ref IsUnitless.
@see @ref sqrt(), @ref Vector::lengthInverted()
@m_keyword{inversesqrt(),GLSL inversesqrt(),}
*/
template<class T> inline typename std::enable_if<IsScalar<T>::value, T>::type sqrtInverted(T a) {
static_assert(IsUnitless<T>::value, "expecting an unitless type");
return T(1)/std::sqrt(a);
}
/** @overload */
template<std::size_t size, class T> inline Vector<size, T> sqrtInverted(const Vector<size, T>& a) {
return Vector<size, T>(T(1))/Math::sqrt(a);
}
/**
@brief Linear interpolation of two values
@param a First value
@ -587,6 +491,124 @@ template<std::size_t size, class T> inline Vector<size, T> fma(const Vector<size
/*@}*/
/**
@{ @name Exponential and power functions
Unlike @m_class{m-doc} [scalar/vector functions](#scalarvector-functions) these
don't work on @ref Magnum::Math::Deg "Deg" / @ref Magnum::Math::Rad "Rad" as
the resulting unit can't be easily expressed.
*/
/**
@brief Integral logarithm
Returns integral logarithm of given number with given base.
@see @ref log2(), @ref log(T)
*/
UnsignedInt MAGNUM_EXPORT log(UnsignedInt base, UnsignedInt number);
/**
@brief Base-2 integral logarithm
Returns integral logarithm of given number with base `2`.
@see @ref log(UnsignedInt, UnsignedInt), @ref log(T)
*/
UnsignedInt MAGNUM_EXPORT log2(UnsignedInt number);
/**
@brief Natural logarithm
Returns natural (base @f$ e @f$) logarithm of given number.
@see @ref Constants::e(), @ref log(UnsignedInt, UnsignedInt), @ref log2()
*/
template<class T> inline T log(T number) { return std::log(number); }
/**
@brief Natural exponential
Returns @f$ e^x @f$.
@see @ref Constants::e(), @ref pow(T, T)
*/
template<class T> inline T exp(T exponent) { return std::exp(exponent); }
/**
@brief Integral power
Returns integral power of base to the exponent. Works only on types that
satisfy @ref IsUnitless.
@see @ref pow(T, T)
*/
template<UnsignedInt exponent, class T> constexpr typename std::enable_if<IsScalar<T>::value, T>::type pow(T base) {
static_assert(IsUnitless<T>::value, "expected an unitless type");
return Implementation::Pow<exponent>::pow(base);
}
/** @overload */
template<UnsignedInt exponent, std::size_t size, class T> inline Vector<size, T> pow(const Vector<size, T>& base) {
Vector<size, T> out{NoInit};
for(std::size_t i = 0; i != size; ++i)
out[i] = Math::pow<exponent>(base[i]);
return out;
}
/**
@brief Power
Returns power of @p base to the @p exponent. Works only on types that satisfy
@ref IsUnitless.
@see @ref pow(T), @ref exp()
*/
template<class T> inline typename std::enable_if<IsScalar<T>::value, T>::type pow(T base, T exponent) {
static_assert(IsUnitless<T>::value, "expected an unitless type");
return std::pow(base, exponent);
}
/** @overload */
template<std::size_t size, class T> inline Vector<size, T> pow(const Vector<size, T>& base, T exponent) {
Vector<size, T> out{NoInit};
for(std::size_t i = 0; i != size; ++i)
out[i] = Math::pow(base[i], exponent);
return out;
}
/**
@brief Square root
Works only on types that satisfy @ref IsUnitless.
@see @ref sqrtInverted(), @ref Vector::length(), @ref sqrt(const Dual<T>&)
*/
template<class T> inline typename std::enable_if<IsScalar<T>::value, T>::type sqrt(T a) {
static_assert(IsUnitless<T>::value, "expecting an unitless type");
return std::sqrt(a);
}
/** @overload */
template<std::size_t size, class T> inline Vector<size, T> sqrt(const Vector<size, T>& a) {
Vector<size, T> out{NoInit};
for(std::size_t i = 0; i != size; ++i)
out[i] = Math::sqrt(a[i]);
return out;
}
/**
@brief Inverse square root
Works only on types that satisfy @ref IsUnitless.
@see @ref sqrt(), @ref Vector::lengthInverted()
@m_keyword{inversesqrt(),GLSL inversesqrt(),}
*/
template<class T> inline typename std::enable_if<IsScalar<T>::value, T>::type sqrtInverted(T a) {
static_assert(IsUnitless<T>::value, "expecting an unitless type");
return T(1)/std::sqrt(a);
}
/** @overload */
template<std::size_t size, class T> inline Vector<size, T> sqrtInverted(const Vector<size, T>& a) {
return Vector<size, T>(T(1))/Math::sqrt(a);
}
/*@}*/
}}
#ifdef MAGNUM_BUILD_DEPRECATED

9
src/Magnum/Math/FunctionsBatch.h

@ -36,6 +36,13 @@
namespace Magnum { namespace Math {
/**
@{ @name Batch functions
These functions process an ubounded range of values, as opposed to single
vectors or scalars.
*/
/**
@brief Minimum of a range
@ -124,6 +131,8 @@ template<class T, std::size_t size> inline std::pair<T, T> minmax(const T(&array
return minmax(Corrade::Containers::arrayView(array));
}
/*@}*/
}}
#endif

10
src/Magnum/Math/Packing.h

@ -33,6 +33,14 @@
namespace Magnum { namespace Math {
/**
@{ @name Packing and unpacking functions
Similarly to @m_class{m-doc} [scalar/vector functions](#scalarvector-functions)
these work on both scalars and vectors, including @ref Magnum::Math::Deg "Deg"
and @ref Magnum::Math::Rad "Rad".
*/
namespace Implementation {
template<class T, UnsignedInt bits = sizeof(T)*8> inline constexpr T bitMax() {
@ -209,6 +217,8 @@ template<std::size_t size> Vector<size, Float> unpackHalf(const Vector<size, Uns
return out;
}
/*@}*/
}}
#endif

Loading…
Cancel
Save