File indexing completed on 2024-06-16 04:16:10

0001 /*
0002     SPDX-FileCopyrightText: 2011 Silvio Heinrich <plassy@web.de>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #ifndef H_KIS_RADIAN_H
0008 #define H_KIS_RADIAN_H
0009 
0010 #include <cmath>
0011 
0012 #define PI       3.14159265358979323846
0013 #define PI2      6.28318530717958647693 // PI * 2.0
0014 #define TO_DEG   57.2957795130823208768 // 180.0 / PI
0015 #define TO_RAD   0.01745329251994329577 // PI / 180.0
0016 #define RAD_360  6.28318530717958647693 // 360  = 2.0*PI
0017 #define RAD_270  4.71238898038468985769 // 270° = 3.0*PI / 2.0
0018 #define RAD_180  3.14159265358979323846 // 180° = PI
0019 #define RAD_90   1.57079632679489661923 // 90°  = PI/2.0
0020 
0021 
0022 template<class TReal> class KisRadian;
0023 
0024 namespace _Private
0025 {
0026 struct Value
0027 {
0028     template<class T>
0029     inline static const T& get(const T& value) { return value; }
0030 
0031     template<class T>
0032     inline static const T& get(const KisRadian<T>& rad) { return rad.value(); }
0033 };
0034 }
0035 
0036 template<class TReal>
0037 class KisRadian
0038 {
0039 public:
0040 
0041     KisRadian():
0042         m_value(TReal(0)) { }
0043 
0044     template<class U>
0045     KisRadian(const KisRadian<U>& rad):
0046         m_value(rad.m_value) { }
0047     
0048     template<class U>
0049     KisRadian(const U& rad) {
0050         m_value = normalizeRadians(_Private::Value::get(rad));
0051     }
0052     
0053     static TReal normalizeRadians(TReal rad) {
0054         rad = std::fmod((TReal)rad, (TReal)PI2);
0055         return rad < TReal(0) ? (rad + PI2) : rad;
0056     }
0057     
0058     static TReal normalizeDegrees(TReal deg) {
0059         deg = std::fmod(deg, TReal(360));
0060         return deg < TReal(0) ? (deg + TReal(360)) : deg;
0061     }
0062     
0063     static KisRadian from90Deg() {
0064         KisRadian rad;
0065         rad.m_value = RAD_90;
0066         return rad;
0067     }
0068     
0069     static KisRadian from180Deg() {
0070         KisRadian rad;
0071         rad.m_value = RAD_180;
0072         return rad;
0073     }
0074     
0075     static KisRadian from270Deg() {
0076         KisRadian rad;
0077         rad.m_value = RAD_270;
0078         return rad;
0079     }
0080     
0081     static KisRadian fromDegrees(const TReal& deg) { return KisRadian(deg * TO_RAD); }
0082     static TReal     toRadians  (const TReal& deg) { return normalizeDegrees(deg) * TO_RAD; }
0083     static TReal     toDegrees  (const TReal& rad) { return normalizeRadians(rad) * TO_DEG; }
0084     
0085     const TReal& value  () const { return m_value;          }
0086     TReal        degrees() const { return m_value * TO_DEG; }
0087     
0088     TReal scaled(const TReal& min, const TReal& max) const {
0089         return min + (m_value / PI2) * (max - min);
0090     }
0091     
0092     // ------ operator = ---------------------------------------------------- //
0093     
0094     template<class U>
0095     KisRadian& operator = (const U& rad) {
0096         m_value = normalizeRadians(_Private::Value::get(rad));
0097         return *this;
0098     }
0099     
0100     template<class U>
0101     KisRadian& operator = (const KisRadian<U>& rad) {
0102         m_value = rad.m_value;
0103         return *this;
0104     }
0105     
0106     // ------ operator + ---------------------------------------------------- //
0107     
0108     template<class U>
0109     KisRadian& operator += (const U& rad) {
0110         m_value = normalizeRadians(m_value + _Private::Value::get(rad));
0111         return *this;
0112     }
0113     
0114     
0115     friend KisRadian operator + (const KisRadian& l, const KisRadian& r) {
0116         KisRadian rad(l);
0117         rad += r;
0118         return rad;
0119     }
0120     
0121     // ------ operator - ---------------------------------------------------- //
0122     
0123     template<class U>
0124     KisRadian& operator -= (const U& rad) {
0125         m_value = normalizeRadians(m_value - _Private::Value::get(rad));
0126         return *this;
0127     }
0128     
0129     friend KisRadian operator - (const KisRadian& l, const KisRadian& r) {
0130         KisRadian rad(l);
0131         rad -= r;
0132         return rad;
0133     }
0134     
0135     // ------ operator * ---------------------------------------------------- //
0136     
0137     template<class U>
0138     KisRadian& operator *= (const U& rad) {
0139         m_value = normalizeRadians(m_value * _Private::Value::get(rad));
0140         return *this;
0141     }
0142 
0143     friend KisRadian operator * (const KisRadian& l, const KisRadian& r) {
0144         KisRadian rad(l);
0145         rad *= r;
0146         return rad;
0147     }
0148     
0149     // ------ operator / ---------------------------------------------------- //
0150     
0151     template<class U>
0152     KisRadian& operator /= (const U& rad) {
0153         m_value = normalizeRadians(m_value / _Private::Value::get(rad));
0154         return *this;
0155     }
0156 
0157     friend KisRadian operator / (const KisRadian& l, const KisRadian& r) {
0158         KisRadian rad(l);
0159         rad /= r;
0160         return rad;
0161     }
0162     
0163     // ------ operator % ---------------------------------------------------- //
0164     
0165     template<class U>
0166     KisRadian& operator %= (const U& rad) {
0167         m_value = normalizeRadians(std::fmod(m_value, TReal(_Private::Value::get(rad))));
0168         return *this;
0169     }
0170     
0171     
0172     friend KisRadian operator % (const KisRadian& l, const KisRadian& r) {
0173         KisRadian rad(l);
0174         rad %= r;
0175         return rad;
0176     }
0177     
0178 private:
0179     TReal m_value;
0180 };
0181 
0182 #endif // H_KIS_RADIAN_H