Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef TCG_NUMERIC_OPS_H
Toshihiro Shimizu 890ddd
#define TCG_NUMERIC_OPS_H
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// tcg includes
Toshihiro Shimizu 890ddd
#include "traits.h"
Toshihiro Shimizu 890ddd
#include "sfinae.h"
Toshihiro Shimizu 890ddd
#include "macros.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// STD includes
Toshihiro Shimizu 890ddd
#include <cmath></cmath>
Toshihiro Shimizu 890ddd
#include <limits></limits>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  \file     tcg_numeric_ops.h
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  \brief    This file contains small function snippets to manipulate scalars
Toshihiro Shimizu 890ddd
            or numerical objects.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//***************************************************************************
Toshihiro Shimizu 890ddd
//    Numerical Operations
Toshihiro Shimizu 890ddd
//***************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace tcg
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  Contains small function snippets to manipulate scalars
Toshihiro Shimizu 890ddd
  or numerical objects.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
namespace numeric_ops
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename scalar=""></typename>
Toshihiro Shimizu 890ddd
//inline Scalar NaN() {return (std::numeric_limits<scalar>::quiet_NaN)();}</scalar>
Toshihiro Shimizu 890ddd
inline Scalar NaN()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return (std::numeric_limits<scalar>::max)();</scalar>
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  Calculates the sign of a scalar.
Toshihiro Shimizu 890ddd
  \remark  This function returns the \a integral values \p 1 in case the input value is
Toshihiro Shimizu 890ddd
           \a positive, \p -1 in case it's negative, and \p 0 in case it's \a exactly \p 0.
Toshihiro Shimizu 890ddd
  \return  The sign of the input scalar.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
template <typename scalar=""></typename>
Toshihiro Shimizu 890ddd
inline int sign(Scalar val, Scalar tol = 0)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return (val > tol) ? 1 : (val < -tol) ? -1 : 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Computes the nearest integer not greater in magnitude than the given value
Toshihiro Shimizu 890ddd
template <typename scalar=""></typename>
Toshihiro Shimizu 890ddd
Scalar trunc(Scalar val)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return (val < 0) ? std::ceil(val) : std::floor(val);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Computes the nearest integer \b strictly not greater in magnitude than the given value
Toshihiro Shimizu 890ddd
template <typename scalar=""></typename>
Toshihiro Shimizu 890ddd
Scalar truncStrict(Scalar val)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return (val < 0) ? std::floor(val + 1) : std::ceil(val - 1);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Computes the nearest integer not lesser in magnitude than the given value
Toshihiro Shimizu 890ddd
template <typename scalar=""></typename>
Toshihiro Shimizu 890ddd
Scalar grow(Scalar val)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return (val < 0) ? std::floor(val) : std::ceil(val);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Computes the nearest integer \b strictly not lesser in magnitude than the given value
Toshihiro Shimizu 890ddd
template <typename scalar=""></typename>
Toshihiro Shimizu 890ddd
Scalar growStrict(Scalar val)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return (val < 0) ? std::ceil(val - 1) : std::floor(val + 1);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename scalar=""></typename>
Toshihiro Shimizu 890ddd
inline bool areNear(Scalar a, Scalar b, Scalar tolerance)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return (std::abs(b - a) < tolerance);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename scalar=""></typename>
Toshihiro Shimizu 890ddd
inline typename tcg::disable_if<tcg::is_floating_point<scalar>::value, Scalar>::type</tcg::is_floating_point<scalar>
Toshihiro Shimizu 890ddd
mod(Scalar val, Scalar mod)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	Scalar m = val % mod;
Toshihiro Shimizu 890ddd
	return (m >= 0) ? m : m + mod;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename scalar=""></typename>
Toshihiro Shimizu 890ddd
inline typename tcg::enable_if<tcg::is_floating_point<scalar>::value, Scalar>::type</tcg::is_floating_point<scalar>
Toshihiro Shimizu 890ddd
mod(Scalar val, Scalar mod)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	Scalar m = fmod(val, mod);
Toshihiro Shimizu 890ddd
	return (m >= 0) ? m : m + mod;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename scalar=""></typename>
Toshihiro Shimizu 890ddd
inline Scalar mod(Scalar val, Scalar a, Scalar b)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return a + mod(val - a, b - a);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Returns the modular shift value with minimal abs:  <tt>mod(val2, m) = mod(val1 + shift, m)</tt>
Toshihiro Shimizu 890ddd
template <typename scalar=""></typename>
Toshihiro Shimizu 890ddd
inline Scalar modShift(Scalar val1, Scalar val2, Scalar m)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	Scalar shift1 = mod(val2 - val1, m), shift2 = m - shift1;
Toshihiro Shimizu 890ddd
	return (shift2 < shift1) ? -shift2 : shift1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Returns the modular shift value with minimal abs:  <tt>mod(val2, a, b) = mod(val1 + shift, a, b)</tt>
Toshihiro Shimizu 890ddd
template <typename scalar=""></typename>
Toshihiro Shimizu 890ddd
inline Scalar modShift(Scalar val1, Scalar val2, Scalar a, Scalar b)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return modShift(val1 - a, val2 - a, b - a);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  Returns the \a quotient associated to the remainder calculated with mod().
Toshihiro Shimizu 890ddd
  \return  Integral quotient of the division of \p val by \p d.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
template <typename scalar=""></typename>
Toshihiro Shimizu 890ddd
inline typename tcg::disable_if<tcg::is_floating_point<scalar>::value, Scalar>::type</tcg::is_floating_point<scalar>
Toshihiro Shimizu 890ddd
div(Scalar val, Scalar d)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TCG_STATIC_ASSERT(-3 / 5 == 0);
Toshihiro Shimizu 890ddd
	TCG_STATIC_ASSERT(3 / -5 == 0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return (val < 0 || d < 0) ? (val / d) - 1 : val / d;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  Returns the \a quotient associated to the remainder calculated with mod().
Toshihiro Shimizu 890ddd
  \return  Integral quotient of the division of \p val by \p d.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
template <typename scalar=""></typename>
Toshihiro Shimizu 890ddd
inline typename tcg::enable_if<tcg::is_floating_point<scalar>::value, Scalar>::type</tcg::is_floating_point<scalar>
Toshihiro Shimizu 890ddd
div(Scalar val, Scalar d)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return std::floor(val / d);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  Returns the \a quotient associated to the remainder calculated with mod().
Toshihiro Shimizu 890ddd
  \return  Integral quotient of the division of \p val by <tt>(b-a)</tt>.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
template <typename scalar=""></typename>
Toshihiro Shimizu 890ddd
inline Scalar div(Scalar val, Scalar a, Scalar b)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return div(val - a, b - a);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Linear interpolation of values \p v0 and \p v1 with parameter \p t.
Toshihiro Shimizu 890ddd
template <typename scalar="" t,="" typename=""></typename>
Toshihiro Shimizu 890ddd
inline T lerp(const T &v0, const T &v1, Scalar t)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return (1 - t) * v0 + t * v1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  \brief Computes the second degree Bezier curve of control points \p c0, \p c1 and \p c2
Toshihiro Shimizu 890ddd
         at parameter \p t.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
template <typename scalar="" t,="" typename=""></typename>
Toshihiro Shimizu 890ddd
inline T bezier(const T &c0, const T &c1, const T &c2, Scalar t)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	Scalar one_t = 1 - t, t_one_t = t * one_t;							   // 3  Scalar-Scalar products
Toshihiro Shimizu 890ddd
	return (one_t * one_t) * c0 + (t_one_t + t_one_t) * c1 + (t * t) * c2; // 3  Scalar-T products
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// return (c0 * one_t + c1 * t) * one_t + (c1 * one_t + c2 * t) * t;              // 6 Scalar-T products
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! \deprecated
Toshihiro Shimizu 890ddd
template <typename uscalar=""></typename>
Toshihiro Shimizu 890ddd
inline UScalar GE_2Power(UScalar val)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!val)
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd
	--val;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	UScalar i;
Toshihiro Shimizu 890ddd
	for (i = 0; val; ++i)
Toshihiro Shimizu 890ddd
		val = val >> 1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return 1 << i;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
} // namespace tcg::numeric_ops
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif // TCG_NUMERIC_OPS_H