GeographicLib 2.5
AuxAngle.hpp
Go to the documentation of this file.
1/**
2 * \file AuxAngle.hpp
3 * \brief Header for the GeographicLib::AuxAngle class
4 *
5 * This file is an implementation of the methods described in
6 * - C. F. F. Karney,
7 * <a href="https://doi.org/10.1080/00396265.2023.2217604">
8 * On auxiliary latitudes,</a>
9 * Survey Review 56(395), 165--180 (2024);
10 * preprint
11 * <a href="https://arxiv.org/abs/2212.05818">arXiv:2212.05818</a>.
12 * .
13 * Copyright (c) Charles Karney (2022-2023) <karney@alum.mit.edu> and licensed
14 * under the MIT/X11 License. For more information, see
15 * https://geographiclib.sourceforge.io/
16 **********************************************************************/
17
18#if !defined(GEOGRAPHICLIB_AUXANGLE_HPP)
19#define GEOGRAPHICLIB_AUXANGLE_HPP 1
20
22
23namespace GeographicLib {
24
25 /**
26 * \brief An accurate representation of angles.
27 *
28 * This class is an implementation of the methods described in
29 * - C. F. F. Karney,
30 * <a href="https://doi.org/10.1080/00396265.2023.2217604">
31 * On auxiliary latitudes,</a>
32 * Survey Review 56(395), 165--180 (2024);
33 * preprint
34 * <a href="https://arxiv.org/abs/2212.05818">arXiv:2212.05818</a>.
35 *
36 * An angle is represented be the \e y and \e x coordinates of a point in the
37 * 2d plane. The two coordinates are proportional to the sine and cosine of
38 * the angle. This allows angles close to the cardinal points to be
39 * represented accurately. It also saves on unnecessary recomputations of
40 * trigonometric functions of the angle. Only angles in [&minus;180&deg;,
41 * 180&deg;] can be represented. (A possible extension would be to keep
42 * count of the number of turns.)
43 *
44 * Example of use:
45 * \include example-AuxAngle.cpp
46 **********************************************************************/
48 private:
49 typedef Math::real real;
50 real _y, _x;
51 public:
52 /**
53 * The constructor.
54 *
55 * @param[in] y the \e y coordinate.
56 * @param[in] x the \e x coordinate.
57 *
58 * \note the \e y coordinate is specified \e first.
59 * \warning either \e x or \e y can be infinite, but not both.
60 *
61 * The defaults (\e x = 1 and \e y = 0) are such that
62 * + no arguments gives an angle of 0;
63 * + 1 argument specifies the tangent of the angle.
64 **********************************************************************/
65 explicit AuxAngle(real y = 0, real x = 1) : _y(y), _x(x) {}
66 /**
67 * @return the \e y component. This is the sine of the angle if the
68 * AuxAngle has been normalized.
69 **********************************************************************/
70 Math::real y() const { return _y; }
71 /**
72 * @return the \e x component. This is the cosine of the angle if the
73 * AuxAngle has been normalized.
74 **********************************************************************/
75 Math::real x() const { return _x; }
76 /**
77 * @return a reference to the \e y component. This allows this component
78 * to be altered.
79 **********************************************************************/
80 Math::real& y() { return _y; }
81 /**
82 * @return a reference to the \e x component. This allows this component
83 * to be altered.
84 **********************************************************************/
85 Math::real& x() { return _x; }
86 /**
87 * @return the AuxAngle converted to the conventional angle measured in
88 * degrees.
89 **********************************************************************/
90 Math::real degrees() const;
91 /**
92 * @return the AuxAngle converted to the conventional angle measured in
93 * radians.
94 **********************************************************************/
95 Math::real radians() const;
96 /**
97 * @return the lambertian of the AuxAngle.
98 *
99 * \note the lambertian of an angle &chi; is
100 * lam(&chi;) = asinh(tan(&chi;)).
101 **********************************************************************/
102 Math::real lam() const;
103 /**
104 * @return the lambertian of the AuxAngle in degrees.
105 *
106 * \note the lambertian of an angle &chi; is
107 * lam(&chi;) = asinh(tan(&chi;)).
108 **********************************************************************/
109 Math::real lamd() const;
110 /**
111 * @return the tangent of the angle.
112 **********************************************************************/
113 Math::real tan() const { return _y / _x; }
114 /**
115 * @return a new normalized AuxAngle with the point lying on the unit
116 * circle and the \e y and \e x components are equal to the sine and
117 * cosine of the angle.
118 **********************************************************************/
119 AuxAngle normalized() const;
120 /**
121 * Normalize the AuxAngle in place so that the \e y and \e x components are
122 * equal to the sine and cosine of the angle.
123 **********************************************************************/
124 void normalize() { *this = normalized(); }
125 /**
126 * Set the quadrant for the AuxAngle.
127 *
128 * @param[in] p the AuxAngle from which the quadrant information is taken.
129 * @return the new AuxAngle in the same quadrant as \e p.
130 **********************************************************************/
131 AuxAngle copyquadrant(const AuxAngle& p) const;
132 /**
133 * Add an AuxAngle.
134 *
135 * @param[in] p the AuxAngle to be added.
136 * @return a reference to the new AuxAngle.
137 *
138 * The addition is done in place, altering the current AuxAngle.
139 *
140 * \warning Neither *this nor \e p should have an infinite component. If
141 * necessary, invoke AuxAngle::normalize on these angles first.
142 **********************************************************************/
143 AuxAngle& operator+=(const AuxAngle& p);
144 /**
145 * Construct and return an AuxAngle specied as an angle in degrees.
146 *
147 * @param[in] d the angle measured in degrees.
148 * @return the corresponding AuxAngle.
149 *
150 * This allows a new AuxAngle to be initialized as an angle in degrees with
151 * @code
152 * AuxAngle phi(AuxAngle::degrees(d));
153 * @endcode
154 **********************************************************************/
155 static AuxAngle degrees(real d);
156 /**
157 * Construct and return an AuxAngle specied as an angle in radians.
158 *
159 * @param[in] r the angle measured in radians.
160 * @return the corresponding AuxAngle.
161 *
162 * This allows a new AuxAngle to be initialized as an angle in radians with
163 * @code
164 * AuxAngle phi(AuxAngle::radians(r));
165 * @endcode
166 **********************************************************************/
167 static AuxAngle radians(real r);
168 /**
169 * Construct and return an AuxAngle specied by the lambertian of the angle.
170 *
171 * @param[in] psi the lambertian of the angle.
172 * @return the corresponding AuxAngle.
173 *
174 * This allows a new AuxAngle to be initialized given the lambertian with
175 * @code
176 * AuxAngle chi(AuxAngle::lam(psi));
177 * @endcode
178 *
179 * \note this sets the angle &chi; to gd(&psi;) = atan(sinh(&psi;)).
180 **********************************************************************/
181 static AuxAngle lam(real psi);
182 /**
183 * Construct and return an AuxAngle specied by the lambertian of the angle
184 * in degrees.
185 *
186 * @param[in] psid the lambertian of the angle in degrees.
187 * @return the corresponding AuxAngle.
188 *
189 * This allows a new AuxAngle to be initialized given the lambertian with
190 * @code
191 * AuxAngle chi(AuxAngle::lamd(psid));
192 * @endcode
193 *
194 * \note this sets the angle &chi; to gd(&psi;) = atan(sinh(&psi;)).
195 **********************************************************************/
196 static AuxAngle lamd(real psid);
197 /**
198 * @return a "NaN" AuxAngle.
199 **********************************************************************/
200 static AuxAngle NaN();
201 };
202
204 real y, x;
205 Math::sincosd(d, y, x);
206 return AuxAngle(y, x);
207 }
208
210 using std::sin; using std::cos;
211 return AuxAngle(sin(r), cos(r));
212 }
213
214 inline AuxAngle AuxAngle::lam(real psi) {
215 using std::sinh;
216 return AuxAngle(sinh(psi));
217 }
218
219 inline AuxAngle AuxAngle::lamd(real psid) {
220 using std::sinh;
221 return AuxAngle(sinh(psid * Math::degree()));
222 }
223
225 return Math::atan2d(_y, _x);
226 }
227
229 using std::atan2; return atan2(_y, _x);
230 }
231
232 inline Math::real AuxAngle::lam() const {
233 using std::asinh; return asinh( tan() );
234 }
235
236 inline Math::real AuxAngle::lamd() const {
237 using std::asinh; return asinh( tan() ) / Math::degree();
238 }
239
240} // namespace GeographicLib
241
242#endif // GEOGRAPHICLIB_AUXANGLE_HPP
#define GEOGRAPHICLIB_EXPORT
Definition Constants.hpp:67
GeographicLib::Math::real real
Definition GeodSolve.cpp:28
Header for GeographicLib::Math class.
An accurate representation of angles.
Definition AuxAngle.hpp:47
Math::real y() const
Definition AuxAngle.hpp:70
Math::real x() const
Definition AuxAngle.hpp:75
Math::real radians() const
Definition AuxAngle.hpp:228
Math::real degrees() const
Definition AuxAngle.hpp:224
Math::real lamd() const
Definition AuxAngle.hpp:236
Math::real lam() const
Definition AuxAngle.hpp:232
Math::real tan() const
Definition AuxAngle.hpp:113
AuxAngle(real y=0, real x=1)
Definition AuxAngle.hpp:65
static T degree()
Definition Math.hpp:209
static void sincosd(T x, T &sinx, T &cosx)
Definition Math.cpp:101
static T atan2d(T y, T x)
Definition Math.cpp:199
Namespace for GeographicLib.