Kstars

cachingdms.h
1/*
2 SPDX-FileCopyrightText: 2016 Akarsh Simha <akarsh.simha@kdemail.net>
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 <akarsh@kde.org>
16 */
17
18class 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 */
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 {
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};
a dms subclass that caches its sine and cosine values every time the angle is changed.
Definition cachingdms.h:19
CachingDms operator-()
operator -
double cos() const
Get the cosine of this angle.
Definition cachingdms.h:204
friend CachingDms operator+(const CachingDms &, const CachingDms &)
Addition and subtraction operators.
void setUsing_atan2(const double &y, const double &x)
Sets the angle using atan2()
static CachingDms fromString(const QString &s, bool deg)
Construct an angle from the given string.
bool setFromString(const QString &s, bool isDeg=true) override
Sets the angle from string.
Definition cachingdms.h:120
CachingDms()
Default Constructor.
Definition cachingdms.h:24
void setRadians(const double &a) override
Sets the angle in radians.
Definition cachingdms.h:136
double sin() const
Get the sine of this angle.
Definition cachingdms.h:190
void SinCos(double &s, double &c) const
Get the sine and cosine together.
Definition cachingdms.h:175
void setUsing_asin(const double &sine)
Sets the angle using asin()
void setD(const double &x) override
Sets the angle in degrees supplied as a double.
Definition cachingdms.h:59
void setUsing_acos(const double &cosine)
Sets the angle using acos()
void setD(const int &d, const int &m, const int &s, const int &ms=0) override
Overrides dms::setD()
Definition cachingdms.h:74
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 setH(const double &x) override
Sets the angle in hours, supplied as a double.
Definition cachingdms.h:91
An angle, stored as degrees, but expressible in many ways.
Definition dms.h:38
virtual void setH(const double &x)
Sets floating-point value of angle, in hours.
Definition dms.h:210
void SinCos(double &s, double &c) const
Compute Sine and Cosine of the angle simultaneously.
Definition dms.h:447
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
virtual void setRadians(const double &Rad)
Set angle according to the argument, in radians.
Definition dms.h:333
virtual void setD(const double &x)
Sets floating-point value of angle, in degrees.
Definition dms.h:179
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:19:01 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.