Kstars

cachingdms.h
1 /*
2  SPDX-FileCopyrightText: 2016 Akarsh Simha <[email protected]>
3 
4  SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #pragma once
8 
9 #include "dms.h"
10 
11 /**
12  * @class CachingDms
13  * @short a dms subclass that caches its sine and cosine values every time the angle is changed.
14  * @note This is to be used for those angles where sin/cos is repeatedly computed.
15  * @author Akarsh Simha <[email protected]>
16  */
17 
18 class CachingDms : public dms
19 {
20  public:
21  /**
22  * @short Default Constructor
23  */
24  CachingDms() : dms(), m_sin(NaN::d), m_cos(NaN::d)
25  {
26 #ifdef COUNT_DMS_SINCOS_CALLS
27  m_cacheUsed = true;
28  ++cachingdms_constructor_calls;
29 #endif
30  };
31 
32  /**
33  * @short Degree angle constructor
34  * @param x is the angle in degrees
35  */
36  explicit CachingDms(const double &x);
37 
38  /**
39  * @short QString constructor
40  */
41  explicit CachingDms(const QString &s, bool isDeg = true);
42 
43  /**
44  * @short DMS representation constructor
45  */
46  explicit CachingDms(const int &d, const int &m = 0, const int &s = 0, const int &ms = 0);
47 
48 #ifdef COUNT_DMS_SINCOS_CALLS
49  /**
50  * @short Destructor must count bad cache uses
51  */
52  ~CachingDms();
53 #endif
54 
55  /**
56  * @short Sets the angle in degrees supplied as a double
57  * @note Re-implements dms::setD() with sine/cosine caching
58  */
59  inline void setD(const double &x) override
60  {
61  dms::setD(x);
62  dms::SinCos(m_sin, m_cos);
63 #ifdef COUNT_DMS_SINCOS_CALLS
64  cachingdms_delta -= 2;
65  if (!m_cacheUsed)
66  ++cachingdms_bad_uses;
67  m_cacheUsed = false;
68 #endif
69  }
70 
71  /**
72  * @short Overrides dms::setD()
73  */
74  inline void setD(const int &d, const int &m, const int &s, const int &ms = 0) override
75  {
76  dms::setD(d, m, s, ms);
77  dms::SinCos(m_sin, m_cos);
78 #ifdef COUNT_DMS_SINCOS_CALLS
79  cachingdms_delta -= 2;
80  if (!m_cacheUsed)
81  ++cachingdms_bad_uses;
82  m_cacheUsed = false;
83 #endif
84  }
85 
86  /**
87  * @short Sets the angle in hours, supplied as a double
88  * @note Re-implements dms::setH() with sine/cosine caching
89  * @note While this and other methods internally call setD, we want to avoid unnecessary vtable lookups. We'd rather have inline than virtual when speed matters in general.
90  */
91  inline void setH(const double &x) override
92  {
93  dms::setH(x);
94  dms::SinCos(m_sin, m_cos);
95 #ifdef COUNT_DMS_SINCOS_CALLS
96  cachingdms_delta -= 2;
97  if (!m_cacheUsed)
98  ++cachingdms_bad_uses;
99  m_cacheUsed = false;
100 #endif
101  }
102 
103  /**
104  * @short Sets the angle in HMS form
105  * @note Re-implements dms::setH() with sine/cosine caching
106  */
107  inline void setH(const int &h, const int &m, const int &s, const int &ms = 0) override
108  {
109  dms::setH(h, m, s, ms);
110  dms::SinCos(m_sin, m_cos);
111 #ifdef COUNT_DMS_SINCOS_CALLS
112  cachingdms_delta -= 2;
113 #endif
114  }
115 
116  /**
117  * @short Sets the angle from string
118  * @note Re-implements dms::setFromString()
119  */
120  inline bool setFromString(const QString &s, bool isDeg = true) override
121  {
122  bool retval = dms::setFromString(s, isDeg);
123  dms::SinCos(m_sin, m_cos);
124 #ifdef COUNT_DMS_SINCOS_CALLS
125  cachingdms_delta -= 2;
126  if (!m_cacheUsed)
127  ++cachingdms_bad_uses;
128  m_cacheUsed = false;
129 #endif
130  return retval;
131  }
132 
133  /**
134  * @short Sets the angle in radians
135  */
136  inline void setRadians(const double &a) override
137  {
138  dms::setRadians(a);
139  dms::SinCos(m_sin, m_cos);
140 #ifdef COUNT_DMS_SINCOS_CALLS
141  cachingdms_delta -= 2;
142  if (!m_cacheUsed)
143  ++cachingdms_bad_uses;
144  m_cacheUsed = false;
145 #endif
146  }
147 
148  /**
149  * @short Sets the angle using atan2()
150  * @note The advantage is that we can calculate sin/cos faster because we know the tangent
151  */
152  void setUsing_atan2(const double &y, const double &x);
153 
154  /**
155  * @short Sets the angle using asin()
156  * @param sine Sine of the angle
157  * @note The advantage is that we can cache the sine value supplied
158  * @note The limited range of asin must be borne in mind
159  */
160  void setUsing_asin(const double &sine);
161 
162  /**
163  * @short Sets the angle using acos()
164  * @param cosine Cosine of the angle
165  * @note The advantage is that we can cache the cosine value supplied
166  * @note The limited range of acos must be borne in mind
167  */
168  void setUsing_acos(const double &cosine);
169 
170  /**
171  * @short Get the sine and cosine together
172  * @note Re-implements dms::SinCos()
173  * @note This just uses the cached values assuming that they are good
174  */
175  inline void SinCos(double &s, double &c) const
176  {
177  s = m_sin;
178  c = m_cos;
179 #ifdef COUNT_DMS_SINCOS_CALLS
180  cachingdms_delta += 2;
181  m_cacheUsed = true;
182 #endif
183  }
184 
185  /**
186  * @short Get the sine of this angle
187  * @note Re-implements dms::sin()
188  * @note This just uses the cached value assuming that it is good
189  */
190  inline double sin() const
191  {
192 #ifdef COUNT_DMS_SINCOS_CALLS
193  ++cachingdms_delta;
194  m_cacheUsed = true;
195 #endif
196  return m_sin;
197  }
198 
199  /**
200  * @short Get the cosine of this angle
201  * @note Re-implements dms::cos()
202  * @note This just uses the cached value assuming that it is good
203  */
204  inline double cos() const
205  {
206 #ifdef COUNT_DMS_SINCOS_CALLS
207  ++cachingdms_delta;
208  m_cacheUsed = true;
209 #endif
210  return m_cos;
211  }
212 
213  /**
214  * @short Construct an angle from the given string
215  * @note Re-implements dms::fromString()
216  */
217  static CachingDms fromString(const QString &s, bool deg);
218 
219  /**
220  * @short operator -
221  * @note In addition to negating the angle, we negate the sine value
222  */
224 
225  /**
226  * @short Casting constructor
227  */
228  CachingDms(const dms &angle);
229 
230 #ifdef COUNT_DMS_SINCOS_CALLS
231  /**
232  * Copy constructor that sets m_cacheUsed to true
233  */
234  CachingDms(const CachingDms &o);
235  CachingDms &operator=(const CachingDms &o);
236 #endif
237 
238  private:
239  double m_sin, m_cos; // Cached values
240 
241  /**
242  * @short Private constructor used to create a CachingDms with known sine and cosine
243  */
244  explicit CachingDms(const double &degrees, const double &sine, const double &cosine)
245  : dms(degrees), m_sin(sine), m_cos(cosine)
246  {
247 #ifdef COUNT_DMS_SINCOS_CALLS
248  ++cachingdms_constructor_calls;
249  m_cacheUsed = false;
250 #endif
251  }
252 
253  /**
254  * @short Addition and subtraction operators
255  * @note Uses trigonometric identities to find the new trigonometric values
256  * @note Avoid repeated use, as the round-off errors will accumulate!
257  */
258  friend CachingDms operator+(const CachingDms &, const CachingDms &);
259  friend CachingDms operator-(const CachingDms &, const CachingDms &);
260  friend CachingDms operator+(const dms &a, const CachingDms &b);
261  friend CachingDms operator-(const dms &a, const CachingDms &b);
262  friend CachingDms operator+(const CachingDms &a, const dms &b);
263  friend CachingDms operator-(const CachingDms &a, const dms &b);
264 
265 #ifdef COUNT_DMS_SINCOS_CALLS
266  private:
267  mutable bool m_cacheUsed;
268 
269  public:
270  static unsigned long cachingdms_constructor_calls;
271  static long cachingdms_delta; // difference of ( trig function calls ) - ( trig computations )
272  static unsigned long cachingdms_bad_uses;
273 #endif
274 };
double sin() const
Get the sine of this angle.
Definition: cachingdms.h:190
void setD(const double &x) override
Sets the angle in degrees supplied as a double.
Definition: cachingdms.h:59
virtual void setD(const double &x)
Sets floating-point value of angle, in degrees.
Definition: dms.h:179
void setUsing_atan2(const double &y, const double &x)
Sets the angle using atan2()
Definition: cachingdms.cpp:62
a dms subclass that caches its sine and cosine values every time the angle is changed.
Definition: cachingdms.h:18
void setH(const int &h, const int &m, const int &s, const int &ms=0) override
Sets the angle in HMS form.
Definition: cachingdms.h:107
void SinCos(double &s, double &c) const
Get the sine and cosine together.
Definition: cachingdms.h:175
void SinCos(double &s, double &c) const
Compute Sine and Cosine of the angle simultaneously.
Definition: dms.h:444
virtual void setH(const double &x)
Sets floating-point value of angle, in hours.
Definition: dms.h:210
CachingDms()
Default Constructor.
Definition: cachingdms.h:24
void setRadians(const double &a) override
Sets the angle in radians.
Definition: cachingdms.h:136
void setD(const int &d, const int &m, const int &s, const int &ms=0) override
Overrides dms::setD()
Definition: cachingdms.h:74
double cos() const
Get the cosine of this angle.
Definition: cachingdms.h:204
void setH(const double &x) override
Sets the angle in hours, supplied as a double.
Definition: cachingdms.h:91
virtual bool setFromString(const QString &s, bool isDeg=true)
Attempt to parse the string argument as a dms value, and set the dms object accordingly.
Definition: dms.cpp:48
friend CachingDms operator+(const CachingDms &, const CachingDms &)
Addition and subtraction operators.
Definition: cachingdms.cpp:176
An angle, stored as degrees, but expressible in many ways.
Definition: dms.h:37
virtual void setRadians(const double &Rad)
Set angle according to the argument, in radians.
Definition: dms.h:333
static CachingDms fromString(const QString &s, bool deg)
Construct an angle from the given string.
Definition: cachingdms.cpp:121
CachingDms operator-()
operator -
Definition: cachingdms.cpp:128
void setUsing_acos(const double &cosine)
Sets the angle using acos()
Definition: cachingdms.cpp:107
bool setFromString(const QString &s, bool isDeg=true) override
Sets the angle from string.
Definition: cachingdms.h:120
void setUsing_asin(const double &sine)
Sets the angle using asin()
Definition: cachingdms.cpp:93
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Wed Sep 27 2023 04:02:08 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.