|
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
|