22 #ifndef CRNTrigonometry_HEADER
23 #define CRNTrigonometry_HEADER
61 template<
typename Unit>
inline double Cosine(
typename Unit::type angle) noexcept
70 template<
typename Unit>
inline double Sine(
typename Unit::type angle) noexcept
79 template<
typename Unit>
inline double Tangent(
typename Unit::type angle) noexcept
90 static double costab[256];
91 static bool init =
false;
95 for (
int tmp = 0; tmp < 256; ++tmp)
107 static double sintab[256];
108 static bool init =
false;
112 for (
int tmp = 0; tmp < 256; ++tmp)
115 return sintab[angle];
124 static double tantab[256];
125 static bool init =
false;
129 for (
int tmp = 0; tmp < 256; ++tmp)
132 return tantab[angle];
139 template<
typename Unit>
struct Angle
143 constexpr
Angle() noexcept(std::is_nothrow_constructible<typename
Unit::type>::
value)
146 inline Angle(
typename Unit::type val) noexcept(std::is_nothrow_constructible<typename Unit::type>::value)
150 while (tmp >= Unit::VAL2PI)
154 value =
typename Unit::type(tmp);
158 std::is_nothrow_constructible<typename U::type>::value &&
163 while (tmp >= Unit::VAL2PI)
167 value =
typename Unit::type(tmp);
175 template<
typename U>
inline typename U::type
Get() const noexcept(
176 std::is_nothrow_constructible<typename U::type>::
value &&
184 {
Angle a(Unit::VAL2PI);
return a -= *
this; }
187 inline const Angle&
operator+=(
typename Unit::type angle) noexcept(std::is_nothrow_copy_assignable<typename Unit::type>::value)
191 while (tmp >= Unit::VAL2PI)
193 value =
typename Unit::type(tmp);
197 inline const Angle&
operator+=(
const Angle &other) noexcept(std::is_nothrow_copy_assignable<typename Unit::type>::value) {
return this->
operator+=(other.value); }
199 inline Angle operator+(
const Angle &other)
const noexcept(std::is_nothrow_copy_assignable<typename Unit::type>::value){
Angle a(*
this);
return a+= other; }
202 inline const Angle&
operator-=(
typename Unit::type angle) noexcept(std::is_nothrow_copy_assignable<typename Unit::type>::value)
208 value =
typename Unit::type(tmp);
212 inline const Angle&
operator-=(
const Angle &other) noexcept(std::is_nothrow_copy_assignable<typename Unit::type>::value)
215 inline Angle operator-(
const Angle &other)
const noexcept(std::is_nothrow_copy_assignable<typename Unit::type>::value)
216 {
Angle a(*
this);
return a -= other; }
219 inline Angle&
operator*=(
double f) noexcept(std::is_nothrow_copy_assignable<typename Unit::type>::value)
221 auto tmp = double(
value) * f;
222 while (tmp >= Unit::VAL2PI)
226 value =
typename Unit::type(tmp);
230 inline Angle&
operator*(
double f) noexcept(std::is_nothrow_copy_assignable<typename Unit::type>::value) {
auto a(*
this);
return a *= f; }
236 inline double Cos() const noexcept {
return crn::Cosine<Unit>(
value); }
238 inline double Sin() const noexcept {
return crn::Sine<Unit>(
value); }
240 inline double Tan() const noexcept {
return crn::Tangent<Unit>(
value); }
243 static inline Angle Acos(
double cosine) noexcept(std::is_nothrow_constructible<typename Unit::type>::value) {
return Angle<Radian>(acos(cosine)); }
245 static inline Angle Asin(
double sine) noexcept(std::is_nothrow_constructible<typename Unit::type>::value) {
return Angle<Radian>(asin(sine)); }
247 static inline Angle Atan(
double tangent) noexcept(std::is_nothrow_constructible<typename Unit::type>::value) {
return Angle<Radian>(atan(tangent)); }
249 static inline Angle Atan(
double y,
double x) noexcept(std::is_nothrow_constructible<typename Unit::type>::value) {
return Angle<Radian>(atan2(y, x)); }
253 static constexpr
Angle<Unit> TOP() {
return typename Unit::type(Unit::MAXVAL / 4); }
259 template<
class ANGLE>
using Unit =
typename ANGLE::unit;
264 std::is_nothrow_constructible<typename Unit::type>::value &&
265 std::is_nothrow_copy_assignable<typename Unit::type>::value)
275 std::is_nothrow_constructible<typename Unit::type>::value &&
276 std::is_nothrow_copy_assignable<typename Unit::type>::value)
286 std::is_nothrow_constructible<typename Unit::type>::value &&
287 std::is_nothrow_copy_assignable<typename Unit::type>::value)
310 template<
class A>
inline double Cos(
const A &a) noexcept {
return a.Cos(); }
312 inline double Cos(
double a) noexcept {
return cos(a); }
316 template<
class A>
inline double Sin(
const A &a) noexcept {
return a.Sin(); }
318 inline double Sin(
double a) noexcept {
return sin(a); }
322 template<
class A>
inline double Tan(
const A &a) noexcept {
return a.Tan(); }
324 inline double Tan(
double a) noexcept {
return Tan(a); }
328 template<
class A>
inline A
Atan(
double s,
double c) noexcept {
return A::Atan(s, c); }
330 template<>
inline double Atan<double>(
double s,
double c) noexcept {
return atan2(s, c); }
344 std::is_nothrow_constructible<typename Unit::type>::value)
348 if (dist > Unit::MAXVAL / 2)
349 dist = Unit::MAXVAL - dist;
350 return typename Unit::type(dist);
361 const auto dist =
Abs(a1 - a2);
362 return (dist >
M_PI) ? (
M_PI - dist) : dist;
371 template<
typename ITER>
typename std::iterator_traits<ITER>::value_type
AngularMean(ITER beg, ITER en)
373 using return_type =
typename std::iterator_traits<ITER>::value_type;
377 for (ITER it = beg; it != en; ++it)
382 return Atan<return_type>(s, c);
395 auto mdist = std::vector<double>(std::distance(beg, en), 0.0);
396 auto cnt1 = size_t(0);
397 for (
auto it1 = beg; it1 != en; ++cnt1, ++it1)
399 auto cnt2 = cnt1 + 1;
400 for (
auto it2 = std::next(it1); it2 != en; ++cnt2, ++it2)
407 return std::next(beg, std::min_element(mdist.begin(), mdist.end()) - mdist.begin());
418 using angle_type =
typename std::iterator_traits<ITER>::value_type;
423 for (ITER it = beg; it != en; ++it)
425 acc +=
Sqr(AngularDistance<typename angle_type::unit>(mean, *it));
427 return acc / double(std::distance(beg, en));
437 template<
typename ITER>
double AngularVariance(ITER beg, ITER en,
typename std::iterator_traits<ITER>::value_type mean)
439 using angle_type =
typename std::iterator_traits<ITER>::value_type;
443 for (ITER it = beg; it != en; ++it)
445 acc +=
Sqr(AngularDistance<typename angle_type::unit>(mean, *it));
447 return acc / double(std::distance(beg, en));
460 auto c = 0.0, s = 0.0;
461 for (ITER it = beg; it != en; ++it)
466 auto n = double(std::distance(beg, en));
467 return 1.0 - sqrt(
Sqr(c / n) +
Sqr(s / n));
490 template<
typename ITER>
typename std::complex<double>
TrigonometricMoment(ITER beg, ITER en,
typename std::iterator_traits<ITER>::value_type refer,
size_t p)
496 auto c = 0.0, s = 0.0;
497 for (
auto it = beg; it != en; ++it)
499 c +=
Cos(
double(p) * (*it - refer));
500 s +=
Sin(
double(p) * (*it - refer));
502 const auto n = double(std::distance(beg, en));
505 return std::complex<double>(c, s);
521 return std::abs(m2) *
Sin(
Angle<Radian>(std::arg(m2)) - 2 * m) / pow(1 - std::abs(m1), 1.5);
537 return (std::abs(m2) *
Cos(
Angle<Radian>(std::arg(m2)) - 2 * m) - pow(std::abs(m1), 4)) /
Sqr(1 - std::abs(m1));
Angle & operator*=(double f) noexcept(std::is_nothrow_copy_assignable< typename Unit::type >::value)
Multiplies by a scalar.
typename TypeInfo< T >::SumType SumType
BoolNotBoolDummy operator-(const BoolNotBoolDummy &, const BoolNotBoolDummy &)
Unit::type AngularDistance(const Angle< Unit > &a1, const Angle< Unit > &a2) noexcept(std::is_nothrow_constructible< typename TypeInfo< typename Unit::type >::DiffType >::value &&std::is_nothrow_copy_assignable< typename TypeInfo< typename Unit::type >::DiffType >::value &&std::is_nothrow_constructible< typename Unit::type >::value)
Distance between two angles.
const Angle & operator-=(typename Unit::type angle) noexcept(std::is_nothrow_copy_assignable< typename Unit::type >::value)
Subtracts an angle.
Angle(typename Unit::type val) noexcept(std::is_nothrow_constructible< typename Unit::type >::value)
Constructor from a value.
double Sine< ByteAngle >(uint8_t angle) noexcept
Sine of a byte angle using a lookup table.
Angle(const Angle< U > &other) noexcept(std::is_nothrow_constructible< typename U::type >::value &&std::is_nothrow_constructible< typename TypeInfo< typename Unit::type >::SumType >::value)
Constructor from any other angle unit.
static constexpr Angle< Unit > RIGHT()
static Angle Asin(double sine) noexcept(std::is_nothrow_constructible< typename Unit::type >::value)
Computes arc sine.
Angle operator-(const Angle &other) const noexcept(std::is_nothrow_copy_assignable< typename Unit::type >::value)
Subtracts an angle.
static constexpr type MAXVAL
double Tan() const noexcept
Computes tangent.
double Cos(const A &a) noexcept
double Sine(typename Unit::type angle) noexcept
Sine of an angle.
static constexpr TypeInfo< type >::SumType VAL2PI
double Atan< double >(double s, double c) noexcept
decltype(std::declval< T >()-std::declval< T >()) DiffType
A safe type to compute a difference (e.g.: a signed type)
const Angle & operator+=(const Angle &other) noexcept(std::is_nothrow_copy_assignable< typename Unit::type >::value)
Adds an angle.
constexpr Angle() noexcept(std::is_nothrow_constructible< typename Unit::type >::value)
Null angle.
static constexpr type MAXVAL
std::iterator_traits< ITER >::value_type AngularMean(ITER beg, ITER en)
Mean of a set of angles.
Angle operator-() const noexcept(std::is_nothrow_copy_assignable< typename Unit::type >::value)
Negative of the angle.
A convenience class for angles units.
double Cosine(typename Unit::type angle) noexcept
Cosine of an angle.
ITER AngularMedian(ITER beg, ITER en)
Mean of a set of angles.
const Angle & operator+=(typename Unit::type angle) noexcept(std::is_nothrow_copy_assignable< typename Unit::type >::value)
Adds an angle.
const Angle & operator-=(const Angle &other) noexcept(std::is_nothrow_copy_assignable< typename Unit::type >::value)
Subtracts an angle.
static constexpr TypeInfo< type >::SumType VAL2PI
U::type Get() const noexcept(std::is_nothrow_constructible< typename U::type >::value &&std::is_nothrow_constructible< typename TypeInfo< typename Unit::type >::SumType >::value)
Conversion to any other angle unit.
BoolNotBoolDummy operator*(const BoolNotBoolDummy &, const BoolNotBoolDummy &)
decltype(std::declval< T >()+std::declval< T >()) SumType
A safe type to compute a sum (e.g.: a larger integer type)
BoolNotBoolDummy operator+(const BoolNotBoolDummy &, const BoolNotBoolDummy &)
constexpr SumType< T > Sqr(const T &v) noexcept(noexcept(v *v))
Returns the square of a value.
static constexpr Angle< Unit > LEFT()
bool operator==(const Angle &other) const noexcept
Comparison operator.
double AngularVariance(ITER beg, ITER en)
Variance of a set of angles.
double Tangent(typename Unit::type angle) noexcept
Tangent of an angle.
double Sin() const noexcept
Computes sine.
A Atan(double s, double c) noexcept
double CircularStdDev(ITER beg, ITER en)
Circular (pseudo) standard deviation of a set of angles.
double Cos() const noexcept
Computes cosine.
Angle operator+(const Angle &other) const noexcept(std::is_nothrow_copy_assignable< typename Unit::type >::value)
Adds an angle.
static constexpr type MAXVAL
static constexpr TypeInfo< type >::SumType VAL2PI
double Tangent< ByteAngle >(uint8_t angle) noexcept
Tangent of a byte angle using a lookup table.
void Abs(Image< T > &img, typename std::enable_if< std::is_arithmetic< T >::value >::type *dummy=nullptr) noexcept
Replaces each pixel by its absolute value.
double AngularKurtosis(ITER beg, ITER en)
Kurtosis of a set of angles.
double CircularVariance(ITER beg, ITER en)
Circular (pseudo) variance of a set of angles.
double Sin(const A &a) noexcept
Angle & operator*(double f) noexcept(std::is_nothrow_copy_assignable< typename Unit::type >::value)
Multiplies by a scalar.
static constexpr Angle< Unit > BOTTOM()
double Tan(const A &a) noexcept
double Cosine< ByteAngle >(uint8_t angle) noexcept
Cosine of a byte angle using a lookup table.
double AngularSkewness(ITER beg, ITER en)
Skewness of a set of angles.
Angle & operator=(const Angle &)=default
typename ANGLE::unit Unit
static constexpr Angle< Unit > TOP()
static Angle Acos(double cosine) noexcept(std::is_nothrow_constructible< typename Unit::type >::value)
Computes arc cosine.
A class containing informations on a type.
std::complex< double > TrigonometricMoment(ITER beg, ITER en, typename std::iterator_traits< ITER >::value_type refer, size_t p)
Trigonometric moment.
static Angle Atan(double y, double x) noexcept(std::is_nothrow_constructible< typename Unit::type >::value)
Computes arc tangent from coordinates.
Invalid argument error (e.g.: nullptr pointer)
static Angle Atan(double tangent) noexcept(std::is_nothrow_constructible< typename Unit::type >::value)
Computes arc tangent.