Isis 3 Programmer Reference
Angle.cpp
1 
6 /* SPDX-License-Identifier: CC0-1.0 */
7 #include "Angle.h"
8 
9 #include <cmath>
10 
11 #include <QDebug>
12 
13 #include "Constants.h"
14 #include "IString.h"
15 #include "IException.h"
16 #include "SpecialPixel.h"
17 
18 namespace Isis {
24  m_radians = Null;
25  }
26 
33  Angle::Angle(double angle, Units unit) {
34  setAngle(angle, unit);
35  }
36 
37 
43  Angle::Angle(const Angle& fromAngle) {
44  m_radians = fromAngle.m_radians;
45  }
46 
47 
54  Angle::Angle(QString angle) {
55  QString::SectionFlag flag = QString::SectionSkipEmpty;
56  bool degreesSucceeded, minutesSucceeded, secondsSucceeded;
57 
58  double degrees = angle.section(' ', 0, 0, flag).toDouble(&degreesSucceeded);
59  double minutes = angle.section(' ', 1, 1, flag).toDouble(&minutesSucceeded);
60  double seconds = angle.section(' ', 2, 2, flag).toDouble(&secondsSucceeded);
61 
62  if (!(degreesSucceeded && minutesSucceeded && secondsSucceeded) ) {
63  QString msg = QObject::tr("[%1] is not a vaid input to Angle. It needs to be of the form: "
64  "\"dd mm ss.ss\"").arg(angle);
65  throw IException(IException::Programmer, msg, _FILEINFO_);
66  }
67 
68  //if the first digit is '-', everything should be negative
69  if (degrees < 0) {
70  minutes = -minutes;
71  seconds = -seconds;
72  }
73 
74  double decimalDegrees = degrees + minutes/60.0 + seconds/3600.0;
75  setAngle(decimalDegrees, Angle::Degrees);
76  }
77 
78 
84  // Help prevent any accidental reuse of an Angle object
85  m_radians = Null;
86  }
87 
88 
95  bool Angle::isValid() const {
96  return m_radians != Isis::Null; // returns false if the value is Null or any other special value
97 // return IsValidPixel(m_radians); // returns false if the value is Null or any other special value
98  }
99 
100 
107  return Angle(360, Degrees);
108  }
109 
110 
118  Angle Angle::operator+(const Angle& angle2) const {
119  if(!isValid() || !angle2.isValid()) return Angle();
120 
121  double ourAngle = radians();
122  double otherAngle = angle2.radians();
123 
124  return Angle(ourAngle + otherAngle, Radians);
125  }
126 
127 
136  Angle Angle::operator-(const Angle& angle2) const {
137  if(!isValid() || !angle2.isValid()) return Angle();
138 
139  double ourAngle = radians();
140  double otherAngle = angle2.radians();
141 
142  return Angle(ourAngle - otherAngle, Radians);
143  }
144 
145 
154  Angle Angle::operator*(double value) const {
155  if(!isValid()) return Angle();
156 
157  return Angle(radians() * value, Radians);
158  }
159 
160 
170  Angle operator *(double mult, Angle angle) {
171  return angle * mult;
172  }
173 
174 
181  Angle Angle::operator/(double value) const {
182  if(!isValid()) return Angle();
183 
184  return Angle(radians() / value, Radians);
185  }
186 
187 
194  double Angle::operator/(Angle value) const {
195  if(!isValid() || !value.isValid()) return Null;
196 
197  return radians() / value.radians();
198  }
199 
200 
208  bool Angle::operator<(const Angle& angle2) const {
209  if(!isValid() || !angle2.isValid()) {
210  IString msg = "Cannot compare a invalid angles with the < operator";
211  throw IException(IException::Programmer, msg, _FILEINFO_);
212  }
213  // != comparison allows for angles that are considered equal to be treated
214  // as being equal. == operator override uses qFuzzyCompare().
215  return (angle(Radians) < angle2.angle(Radians)) && *this != angle2;
216  }
217 
218 
226  bool Angle::operator>(const Angle& angle2) const {
227  if(!isValid() || !angle2.isValid()) {
228  IString msg = "Cannot compare a invalid angles with the > operator";
229  throw IException(IException::Programmer, msg, _FILEINFO_);
230  }
231  // != comparison allows for angles that are considered equal to be treated
232  // as being equal. == operator override uses qFuzzyCompare().
233  return (angle(Radians) > angle2.angle(Radians)) && *this != angle2;
234  }
235 
236 
243  QString Angle::toString(bool includeUnits) const {
244  QString textResult = "";
245 
246  if (isValid()) {
247  textResult = Isis::toString(degrees());
248 
249  if (includeUnits)
250  textResult += " degrees";
251  }
252 
253  return textResult;
254  }
255 
256 
266  double Angle::unitWrapValue(const Units& unit) const {
267  switch (unit) {
268  case Radians:
269  return PI * 2.;
270  break;
271 
272  case Degrees:
273  return 360.;
274  break;
275  }
276 
277  IString msg = "Angle can not interpret the enumerated value [" +
278  IString(unit) + "] as a unit";
279  throw IException(IException::Programmer, msg, _FILEINFO_);
280  }
281 
282 
289  double Angle::angle(const Units& unit) const {
290  // Don't do math on special pixels
291  if(m_radians == Null) {
292  return Null;
293  }
294 
295  double angleValue = Null;
296 
297  switch (unit) {
298  case Radians:
299  angleValue = m_radians;
300  break;
301 
302  case Degrees:
303  angleValue = m_radians * RAD2DEG;
304  break;
305  }
306 
307  if(angleValue == Null) {
308  IString msg = "Angle can not interpret the enumerated value [" +
309  IString(unit) + "] as a unit";
310  throw IException(IException::Programmer, msg, _FILEINFO_);
311  }
312 
313  return angleValue;
314  }
315 
316 
323  void Angle::setAngle(const double &angle,const Units& unit) {
324  // Don't allow non-Null special pixels, Null means no value
325  if (IsSpecial(angle) && angle != Null) {
326  IString msg = "Angle cannot be a non-Null special pixel";
327  throw IException(IException::Programmer, msg, _FILEINFO_);
328  }
329 
330  // Don't do math on special pixels
331  if(angle == Null) {
332  m_radians = Null;
333  return;
334  }
335 
336  switch (unit) {
337  case Radians:
338  m_radians = angle;
339  break;
340 
341  case Degrees:
342  m_radians = angle * DEG2RAD;
343  break;
344 
345  default:
346  IString msg = "Angle can not interpret the enumerated value [" +
347  IString(unit) + "] as a unit";
348  throw IException(IException::Programmer, msg, _FILEINFO_);
349  }
350  }
351 
352 }
353 
354 
368 QDebug operator<<(QDebug dbg, const Isis::Angle &angleToPrint) {
369  dbg.nospace() << angleToPrint.radians() << " <radians> ("
370  << angleToPrint.degrees() << " <degrees>)";
371 
372  return dbg.space();
373 }
Isis::Angle::Degrees
@ Degrees
Degrees are generally considered more human readable, 0-360 is one circle, however most math does not...
Definition: Angle.h:56
Isis::Angle::operator*
Angle operator*(double value) const
Multiply this angle by a double and return the resulting angle.
Definition: Angle.cpp:154
Isis::Angle::operator-
Angle operator-(const Angle &angle2) const
Subtract angle value from another and return the resulting angle.
Definition: Angle.cpp:136
Isis::Angle::toString
virtual QString toString(bool includeUnits=true) const
Get the angle in human-readable form.
Definition: Angle.cpp:243
Isis::PI
const double PI
The mathematical constant PI.
Definition: Constants.h:40
Isis::operator*
Angle operator*(double mult, Angle angle)
Multiply this angle by a double and return the resulting angle.
Definition: Angle.cpp:170
Isis::DEG2RAD
const double DEG2RAD
Multiplier for converting from degrees to radians.
Definition: Constants.h:43
Isis::Angle::operator>
bool operator>(const Angle &angle2) const
Test if the other angle is greater than the current angle.
Definition: Angle.cpp:226
Isis::Angle::m_radians
double m_radians
The angle measure, always stored in radians.
Definition: Angle.h:258
Isis::Angle::unitWrapValue
double unitWrapValue(const Units &unit) const
Return wrap value in desired units.
Definition: Angle.cpp:266
Isis::toString
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition: IString.cpp:211
Isis::IsSpecial
bool IsSpecial(const double d)
Returns if the input pixel is special.
Definition: SpecialPixel.h:197
Isis::Angle::operator<
bool operator<(const Angle &angle2) const
Test if the other angle is less than the current angle.
Definition: Angle.cpp:208
Isis::Angle::Units
Units
The set of usable angle measurement units.
Definition: Angle.h:49
Isis::IException
Isis exception class.
Definition: IException.h:91
Isis::Angle
Defines an angle and provides unit conversions.
Definition: Angle.h:45
Isis::Null
const double Null
Value for an Isis Null pixel.
Definition: SpecialPixel.h:95
Isis::IException::Programmer
@ Programmer
This error is for when a programmer made an API call that was illegal.
Definition: IException.h:146
Isis::Angle::~Angle
virtual ~Angle()
Destroys the angle object.
Definition: Angle.cpp:83
Isis::Angle::operator/
Angle operator/(double value) const
Divide this angle by a double.
Definition: Angle.cpp:181
Isis::Angle::isValid
bool isValid() const
This indicates whether we have a legitimate angle stored or are in an unset, or invalid,...
Definition: Angle.cpp:95
Isis::Angle::Angle
Angle()
Constructs a blank angle object which needs a value to be set in order to do any calculations.
Definition: Angle.cpp:23
Isis::Angle::fullRotation
static Angle fullRotation()
Makes an angle to represent a full rotation (0-360 or 0-2pi).
Definition: Angle.cpp:106
Isis::Angle::operator+
Angle operator+(const Angle &angle2) const
Add angle value to another.
Definition: Angle.cpp:118
Isis::Angle::degrees
double degrees() const
Get the angle in units of Degrees.
Definition: Angle.h:232
Isis::Angle::setAngle
virtual void setAngle(const double &angle, const Units &unit)
Set angle value in desired units.
Definition: Angle.cpp:323
Isis::IString
Adds specific functionality to C++ strings.
Definition: IString.h:165
Isis::RAD2DEG
const double RAD2DEG
Multiplier for converting from radians to degrees.
Definition: Constants.h:44
Isis::Angle::angle
virtual double angle(const Units &unit) const
Return angle value in desired units.
Definition: Angle.cpp:289
Isis::Angle::Radians
@ Radians
Radians are generally used in mathematical equations, 0-2*PI is one circle, however these are more di...
Definition: Angle.h:63
Isis
This is free and unencumbered software released into the public domain.
Definition: Apollo.h:16
Isis::Angle::radians
double radians() const
Convert an angle to a double.
Definition: Angle.h:226