1.10
math.h
1/*
2 * Copyright (C) 2018 Microchip Technology Inc. All rights reserved.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6#ifndef EGT_DETAIL_MATH_H
7#define EGT_DETAIL_MATH_H
8
14#include <algorithm>
15#include <cassert>
16#include <cmath>
17#include <stdexcept>
18#include <type_traits>
19
20namespace egt
21{
22inline namespace v1
23{
24namespace detail
25{
26
30template<typename T>
31constexpr T pi()
32{
33 return std::acos(-T(1));
34}
35
39template<typename T>
40constexpr T pi_2()
41{
42 return std::acos(-T(0));
43}
44
46template<class T>
47constexpr T mmod(T a, T n)
48{
49 return a - std::floor(a / n) * n;
50}
51
53template<class T>
54constexpr T angle_diff(T angle_start, T angle_stop, bool clockwise = true)
55{
56 if (clockwise)
57 {
58 angle_stop -= angle_start;
59 if (angle_stop < 0.0f)
60 angle_stop += 360.0f;
61 return angle_stop;
62 }
63
64 angle_stop -= angle_start;
65 return mmod(360.0f - angle_stop, 360.0f);
66}
67
71template <class T>
72constexpr T to_degrees(T radians)
73{
74 return radians * (180.0f / pi<T>());
75}
76
80template <class T>
81constexpr T to_radians(T zero, T degrees)
82{
83 degrees += zero;
84 return degrees * (pi<T>() / 180.0f);
85}
86
88template <class T>
89constexpr const T& clamp(const T& v, const T& lo, const T& hi)
90{
91 return assert(!(hi < lo)),
92 (v < lo) ? lo : (hi < v) ? hi : v;
93}
94
96template <class T>
97constexpr T fabs(T x,
98 // NOLINTNEXTLINE(readability-named-parameter)
99 typename std::enable_if<std::is_floating_point<T>::value>::type* = nullptr)
100{
101 return x >= 0 ? x :
102 x < 0 ? -x :
103 throw std::runtime_error("can't make sense of floating point value");
104}
105
107constexpr bool float_equal(const float f1, const float f2)
108{
109 constexpr auto epsilon = 1.0e-05f;
110 if (fabs(f1 - f2) <= epsilon)
111 return true;
112 return fabs(f1 - f2) <= epsilon * std::max(fabs(f1), fabs(f2));
113}
114
116constexpr bool float_equal(const double f1, const double f2)
117{
118 constexpr auto epsilon = 1.0e-9;
119 if (fabs(f1 - f2) <= epsilon)
120 return true;
121 return fabs(f1 - f2) <= epsilon * std::max(fabs(f1), fabs(f2));
122}
123
134template<class T>
135constexpr T normalize(T value, T min, T max, T target_min, T target_max)
136{
137 assert(!float_equal(min, max));
138 const auto r = ((value - min) / (max - min)) *
139 (target_max - target_min) + target_min;
140 assert(!std::isnan(r));
141 return r;
142}
143
155template<class T>
156constexpr T normalize_to_angle(T value, T min, T max, T angle_start, T angle_stop, bool clockwise = true)
157{
158 assert(!float_equal(min, max));
159 assert(!float_equal(angle_start, angle_stop));
160 const auto a = normalize<T>(value, min, max, 0, angle_diff(angle_start, angle_stop, clockwise));
161 assert(!std::isnan(a));
162 return clockwise ? angle_start + a : angle_start - a;
163}
164
165}
166}
167}
168
169#endif
constexpr T angle_diff(T angle_start, T angle_stop, bool clockwise=true)
Compute the angle different between two angles.
Definition math.h:54
constexpr T mmod(T a, T n)
Floating point safe modulus function.
Definition math.h:47
constexpr T pi_2()
Returns the value of PI/2, accurate to the type used.
Definition math.h:40
constexpr T pi()
Returns the value of PI, accurate to the type used.
Definition math.h:31
constexpr T normalize(T value, T min, T max, T target_min, T target_max)
Normalize a value, given its min and max, to a different target min and max.
Definition math.h:135
constexpr T fabs(T x, typename std::enable_if< std::is_floating_point< T >::value >::type *=nullptr)
constexpr version of fabs/fabsf
Definition math.h:97
constexpr T to_radians(T zero, T degrees)
Convert from degrees to radians.
Definition math.h:81
constexpr bool float_equal(const float f1, const float f2)
Safe equal comparison of float values.
Definition math.h:107
constexpr T normalize_to_angle(T value, T min, T max, T angle_start, T angle_stop, bool clockwise=true)
Normalize a value, given its min and max, to a different target angle min and max.
Definition math.h:156
constexpr const T & clamp(const T &v, const T &lo, const T &hi)
Clamp a value between a hi and low value.
Definition math.h:89
constexpr T to_degrees(T radians)
Convert from radians to degrees.
Definition math.h:72
EGT framework namespace.
Definition animation.h:24