swift
angle.cpp
1 // SPDX-FileCopyrightText: Copyright (C) 2013 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
4 #include "misc/pq/angle.h"
5 
6 #include <cmath>
7 
8 #include "misc/iconlist.h"
9 #include "misc/icons.h"
10 #include "misc/math/constants.h"
11 #include "misc/math/mathutils.h"
12 
13 using namespace swift::misc::math;
14 
15 namespace swift::misc::physical_quantities
16 {
17  CAngle::CAngle(int degrees, int minutes, double seconds)
18  : CPhysicalQuantity(degrees + minutes / 100.0 + seconds / 10000.0, CAngleUnit::sexagesimalDeg())
19  {
20  Q_ASSERT_X((degrees >= 0 && minutes >= 0 && seconds >= 0) || (degrees <= 0 && minutes <= 0 && seconds <= 0),
21  Q_FUNC_INFO, "Same sign required");
22  }
23 
24  CAngle::CAngle(int degrees, double minutes)
25  : CPhysicalQuantity(degrees + minutes / 100.0, CAngleUnit::sexagesimalDeg())
26  {
27  Q_ASSERT_X((degrees >= 0 && minutes >= 0) || (degrees <= 0 && minutes <= 0), Q_FUNC_INFO, "Same sign required");
28  }
29 
30  void CAngle::unifySign(int degrees, int &minutes, double &seconds)
31  {
32  minutes = std::copysign(minutes, degrees == 0 ? minutes : degrees);
33  seconds = std::copysign(seconds, degrees == 0 ? minutes : degrees);
34  }
35 
36  void CAngle::unifySign(int degrees, int &minutes)
37  {
38  if (degrees == 0) { return; }
39  minutes = std::copysign(minutes, degrees);
40  }
41 
42  CIcons::IconIndex CAngle::toIcon() const { return CIcons::StandardIconArrowMediumNorth16; }
43 
45  {
46  double dms = this->value(CAngleUnit::sexagesimalDeg());
47 
48  if (range180Degrees)
49  {
50  dms = std::fmod(dms + 180.0, 360.0);
51  dms += (dms < 0) ? 180.0 : -180.0;
52  }
53 
55  if (dms < 0)
56  {
57  values.sign = -1;
58  dms *= -1.0;
59  }
60 
61  QString str = QStringLiteral("%1").arg(dms, 14, 'f', 10, '0'); // 000.0000000000
62  values.deg = QStringView { str }.mid(0, 3).toInt();
63  values.min = QStringView { str }.mid(4, 2).toInt();
64  values.sec = QStringView { str }.mid(6, 2).toInt();
65  values.fractionalSec = QStringView { str }.mid(8, 6).toInt() / 1000000.0;
66  return values;
67  }
68 
69  double CAngle::piFactor() const { return math::CMathUtils::round(this->value(CAngleUnit::rad()) / c_pi, 6); }
70 
71  const double &CAngle::PI() { return c_pi; }
72 
73  double CAngle::sin() const { return std::sin(this->value(CAngleUnit::rad())); }
74 
75  double CAngle::cos() const { return std::cos(this->value(CAngleUnit::rad())); }
76 
77  double CAngle::tan() const { return std::tan(this->value(CAngleUnit::rad())); }
78 
80  {
81  const double v = normalizeDegrees180(this->value(CAngleUnit::deg()));
82  const CAngleUnit u = this->getUnit();
83  *this = CAngle(v, CAngleUnit::deg());
84  this->switchUnit(u);
85  }
86 
88  {
89  const double v = normalizeDegrees360(this->value(CAngleUnit::deg()));
90  const CAngleUnit u = this->getUnit();
91  *this = CAngle(v, CAngleUnit::deg());
92  this->switchUnit(u);
93  }
94 
96  {
97  CAngle copy(*this);
99  return copy;
100  }
101 
103  {
104  CAngle copy(*this);
105  copy.normalizeTo360Degrees();
106  return copy;
107  }
108 
109  double CAngle::normalizeDegrees180(double degrees, int roundDigits)
110  {
111  double d = CMathUtils::normalizeDegrees360(degrees + 180.0) - 180.0;
112  if (d <= -180.0) { d = 180.0; } // -180 -> 180
113  return roundDigits < 0 ? d : CMathUtils::round(d, roundDigits);
114  }
115 
116  double CAngle::normalizeDegrees360(double degrees, int roundDigits)
117  {
118  const double d = CMathUtils::normalizeDegrees360(degrees);
119  return roundDigits < 0 ? d : CMathUtils::round(d, roundDigits);
120  }
121 } // namespace swift::misc::physical_quantities
IconIndex
Index for each icon, allows to send them via DBus, efficiently store them, etc.
Definition: icons.h:32
static double round(double value, int digits)
Utility round method.
Definition: mathutils.cpp:18
static double normalizeDegrees360(double degrees)
Normalize: 0≤ degrees <360.
Definition: mathutils.cpp:56
Physical unit angle (radians, degrees)
Definition: angle.h:23
CAngle()
Default constructor.
Definition: angle.h:26
double piFactor() const
Value as factor of PI (e.g. 0.5PI)
Definition: angle.cpp:69
CAngle normalizedToPlusMinus180Degrees() const
As [-179.99, 180.0] normalized angle.
Definition: angle.cpp:95
static void unifySign(int degrees, int &minutes, double &seconds)
Minutes and secods will get same sign as degrees.
Definition: angle.cpp:30
DegMinSecFractionalSec asSexagesimalDegMinSec(bool range180Degrees=false) const
As individual values.
Definition: angle.cpp:44
double cos() const
Cosine of angle.
Definition: angle.cpp:75
double sin() const
Sine of angle.
Definition: angle.cpp:73
double tan() const
Tangent of angle.
Definition: angle.cpp:77
void normalizeTo360Degrees()
Normalize to 0-360, [0, 359,99].
Definition: angle.cpp:87
static const double & PI()
PI as convenience method.
Definition: angle.cpp:71
static double normalizeDegrees180(double degrees, int roundDigits=-1)
Normalize: -180< degrees ≤180.
Definition: angle.cpp:109
void normalizeToPlusMinus180Degrees()
Normalize to +- 180deg, [-179.99, 180.0].
Definition: angle.cpp:79
CAngle normalizedTo360Degrees() const
As [0, 359.99] normalized angle.
Definition: angle.cpp:102
swift::misc::CIcons::IconIndex toIcon() const
As icon, not implemented by all classes.
Definition: angle.cpp:42
static double normalizeDegrees360(double degrees, int roundDigits=-1)
Normalize: 0≤ degrees <360.
Definition: angle.cpp:116
Specialized class for angles (degrees, radian).
Definition: units.h:233
static CAngleUnit rad()
Radians.
Definition: units.h:270
static CAngleUnit deg()
Degrees.
Definition: units.h:278
static CAngleUnit sexagesimalDeg()
Sexagesimal degree (degrees, minutes, seconds, decimal seconds)
Definition: units.h:287
A physical quantity such as "5m", "20s", "1500ft/s".
CAngle & switchUnit(const CAngleUnit &newUnit)
Change unit, and convert value to maintain the same quantity.
constexpr double c_pi
PI.
Definition: constants.h:12