Shinya Kitaoka 810553
#pragma once
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 "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
Shinya Kitaoka 120a6e
namespace tcg {
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
*/
Shinya Kitaoka 120a6e
namespace numeric_ops {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename scalar=""></typename>
Shinya Kitaoka 120a6e
// inline Scalar NaN() {return (std::numeric_limits<scalar>::quiet_NaN)();}</scalar>
Shinya Kitaoka 120a6e
inline Scalar NaN() {
Shinya Kitaoka 120a6e
  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.
Shinya Kitaoka 120a6e
  \remark  This function returns the \a integral values \p 1 in case the input
Shinya Kitaoka 120a6e
  value is
Shinya Kitaoka 120a6e
           \a positive, \p -1 in case it's negative, and \p 0 in case it's \a
Shinya Kitaoka 120a6e
  exactly \p 0.
Toshihiro Shimizu 890ddd
  \return  The sign of the input scalar.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
template <typename scalar=""></typename>
Shinya Kitaoka 120a6e
inline int sign(Scalar val, Scalar tol = 0) {
Shinya Kitaoka 120a6e
  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>
Shinya Kitaoka 120a6e
Scalar trunc(Scalar val) {
Shinya Kitaoka 120a6e
  return (val < 0) ? std::ceil(val) : std::floor(val);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
//! Computes the nearest integer \b strictly not greater in magnitude than the
Shinya Kitaoka 120a6e
//! given value
Toshihiro Shimizu 890ddd
template <typename scalar=""></typename>
Shinya Kitaoka 120a6e
Scalar truncStrict(Scalar val) {
Shinya Kitaoka 120a6e
  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>
Shinya Kitaoka 120a6e
Scalar grow(Scalar val) {
Shinya Kitaoka 120a6e
  return (val < 0) ? std::floor(val) : std::ceil(val);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
//! Computes the nearest integer \b strictly not lesser in magnitude than the
Shinya Kitaoka 120a6e
//! given value
Toshihiro Shimizu 890ddd
template <typename scalar=""></typename>
Shinya Kitaoka 120a6e
Scalar growStrict(Scalar val) {
Shinya Kitaoka 120a6e
  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>
Shinya Kitaoka 120a6e
inline bool areNear(Scalar a, Scalar b, Scalar tolerance) {
Shinya Kitaoka 120a6e
  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>
Tact Yoshida f87d66
inline typename std::enable_if::value,
Shinya Kitaoka 120a6e
                                Scalar>::type
Shinya Kitaoka 120a6e
mod(Scalar val, Scalar mod) {
Shinya Kitaoka 120a6e
  Scalar m = val % mod;
Shinya Kitaoka 120a6e
  return (m >= 0) ? m : m + mod;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename scalar=""></typename>
Shinya Kitaoka 120a6e
inline
Tact Yoshida f87d66
    typename std::enable_if<tcg::is_floating_point<scalar>::value, Scalar>::type</tcg::is_floating_point<scalar>
Shinya Kitaoka 120a6e
    mod(Scalar val, Scalar mod) {
Shinya Kitaoka 120a6e
  Scalar m = fmod(val, mod);
Shinya Kitaoka 120a6e
  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>
Shinya Kitaoka 120a6e
inline Scalar mod(Scalar val, Scalar a, Scalar b) {
Shinya Kitaoka 120a6e
  return a + mod(val - a, b - a);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
//! Returns the modular shift value with minimal abs:  <tt>mod(val2, m) =</tt>
Shinya Kitaoka 120a6e
//! mod(val1 + shift, m)
Toshihiro Shimizu 890ddd
template <typename scalar=""></typename>
Shinya Kitaoka 120a6e
inline Scalar modShift(Scalar val1, Scalar val2, Scalar m) {
Shinya Kitaoka 120a6e
  Scalar shift1 = mod(val2 - val1, m), shift2 = m - shift1;
Shinya Kitaoka 120a6e
  return (shift2 < shift1) ? -shift2 : shift1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
//! Returns the modular shift value with minimal abs:  <tt>mod(val2, a, b) =</tt>
Shinya Kitaoka 120a6e
//! mod(val1 + shift, a, b)
Toshihiro Shimizu 890ddd
template <typename scalar=""></typename>
Shinya Kitaoka 120a6e
inline Scalar modShift(Scalar val1, Scalar val2, Scalar a, Scalar b) {
Shinya Kitaoka 120a6e
  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>
Tact Yoshida f87d66
inline typename std::enable_if::value,
Shinya Kitaoka 120a6e
                                Scalar>::type
Shinya Kitaoka 120a6e
div(Scalar val, Scalar d) {
Shinya Kitaoka 120a6e
  TCG_STATIC_ASSERT(-3 / 5 == 0);
Shinya Kitaoka 120a6e
  TCG_STATIC_ASSERT(3 / -5 == 0);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  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>
Shinya Kitaoka 120a6e
inline
Tact Yoshida f87d66
    typename std::enable_if<tcg::is_floating_point<scalar>::value, Scalar>::type</tcg::is_floating_point<scalar>
Shinya Kitaoka 120a6e
    div(Scalar val, Scalar d) {
Shinya Kitaoka 120a6e
  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>
Shinya Kitaoka 120a6e
inline Scalar div(Scalar val, Scalar a, Scalar b) {
Shinya Kitaoka 120a6e
  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>
Shinya Kitaoka 120a6e
inline T lerp(const T &v0, const T &v1, Scalar t) {
Shinya Kitaoka 120a6e
  return (1 - t) * v0 + t * v1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Shinya Kitaoka 120a6e
  \brief Computes the second degree Bezier curve of control points \p c0, \p c1
Shinya Kitaoka 120a6e
  and \p c2
Toshihiro Shimizu 890ddd
         at parameter \p t.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
template <typename scalar="" t,="" typename=""></typename>
Shinya Kitaoka 120a6e
inline T bezier(const T &c0, const T &c1, const T &c2, Scalar t) {
Shinya Kitaoka 120a6e
  Scalar one_t = 1 - t, t_one_t = t * one_t;  // 3  Scalar-Scalar products
Shinya Kitaoka 120a6e
  return (one_t * one_t) * c0 + (t_one_t + t_one_t) * c1 +
Shinya Kitaoka 120a6e
         (t * t) * c2;  // 3  Scalar-T products
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // return (c0 * one_t + c1 * t) * one_t + (c1 * one_t + c2 * t) * t;
Shinya Kitaoka 120a6e
  // // 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>
Shinya Kitaoka 120a6e
inline UScalar GE_2Power(UScalar val) {
Shinya Kitaoka 120a6e
  if (!val) return 0;
Shinya Kitaoka 120a6e
  --val;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  UScalar i;
Shinya Kitaoka 120a6e
  for (i = 0; val; ++i) val = val >> 1;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return 1 << i;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Shinya Kitaoka 120a6e
}  // namespace tcg::numeric_ops
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
#endif  // TCG_NUMERIC_OPS_H