Basic elevation optimisation channel
[tecorrec.git] / geo / tcGeo.h
blobcc6cbdfceaa633aaacdc21d4e080e9e0962098e6
1 /***************************************************************************
2 * This file is part of Tecorrec. *
3 * Copyright 2008 James Hogan <james@albanarts.com> *
4 * *
5 * Tecorrec is free software: you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation, either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * Tecorrec is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with Tecorrec. If not, write to the Free Software Foundation, *
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
18 ***************************************************************************/
20 #ifndef _tcGeo_h_
21 #define _tcGeo_h_
23 /**
24 * @file tcGeo.h
25 * @brief Geographical coordinates.
28 #include <Vector.h>
29 #include <Matrix.h>
31 #include <QString>
32 #include <QObject>
34 #include <cmath>
36 /// Use doubles for angles.
37 typedef double tcGeoAngle;
39 class tcGeoAngleDMS
41 public:
42 tcGeoAngleDMS(tcGeoAngle angle, bool latitude)
43 : latitude(latitude)
45 positive = (angle >= 0.0);
46 if (!positive)
48 angle = -angle;
50 angle *= 180.0 / M_PI;
51 degrees = (int)floor(angle);
52 angle -= degrees;
53 angle *= 60.0;
54 arcmins = (int)floor(angle);
55 angle -= arcmins;
56 arcsecs = angle * 60.0;
59 operator QString () const
61 return QObject::tr("%1\xB0%2'%3\"%4", "degrees, arcminutes, arcseconds, N/S/E/W")
62 .arg(degrees)
63 .arg(arcmins, 2, 10, QLatin1Char('0'))
64 .arg(arcsecs, 5, 'f', 2, QLatin1Char('0'))
65 .arg(latitude
66 ? (positive ? QObject::tr("N", "north") : QObject::tr("S", "south"))
67 : (positive ? QObject::tr("E", "east") : QObject::tr("W", "west"))
71 bool latitude;
72 bool positive;
73 int degrees;
74 int arcmins;
75 double arcsecs;
78 /// Geographical coordinates.
79 class tcGeo
81 public:
84 * Constructors + destructor
87 /// Primary constructor.
88 tcGeo()
89 : m_longitude(0.0)
90 , m_latitude(0.0)
94 /// Primary constructor.
95 tcGeo(const tcGeoAngle lon, const tcGeoAngle lat)
96 : m_longitude(lon)
97 , m_latitude(lat)
101 /// Construct from a vector.
102 tcGeo(maths::Vector<3,double> vec, bool normalized)
104 if (!normalized)
106 vec.normalize();
108 m_longitude = atan2(vec[0], -vec[1]);
109 m_latitude = asin(vec[2]);
113 * Conversions
116 /// Convert to a 3d direction vector.
117 operator maths::Vector<3,float> () const
119 float z = sinf(m_latitude);
120 float xy = cosf(m_latitude);
121 return maths::Vector<3,float>(xy*sinf(m_longitude), -xy*cosf(m_longitude), z);
124 /// Convert to a 3d direction vector.
125 operator maths::Vector<3,double> () const
127 //return this->operator maths::Matrix<3,double>() * maths::Vector<3,double>(0.0, 0.0, 1.0);
128 double z = sin(m_latitude);
129 double xy = cos(m_latitude);
130 return maths::Vector<3,double>(xy*sin(m_longitude), -xy*cos(m_longitude), z);
133 /// Convert to a rotation matrix.
134 operator maths::Matrix<3,double> () const
136 return maths::Matrix<3,double>(
137 maths::RotateRadMatrix44('x', m_latitude-M_PI/2)
139 maths::RotateRadMatrix44('z', -m_longitude)
141 double sina = sin(m_longitude);
142 double cosa = cos(m_longitude);
143 double sine = sin(m_latitude-M_PI/2);
144 double cose = cos(m_latitude-M_PI/2);
146 [[cos(a), sin(a), 0],
147 [-sin(a) cos(-1/2 PI+e),cos(a) cos(-1/2 PI+e), sin(-1/2 PI+e)],
148 [sin(a) sin(-1/2 PI+e), -cos(a) sin(-1/2 PI+e),cos(-1/2 PI+e)]]
150 return maths::Matrix<3,double>(
151 // First column
152 maths::Vector<3,double>(cosa, -sina*cose, sina*sine),
153 // Second column
154 maths::Vector<3,double>(sina, cosa*cose, -cosa*sine),
155 // Third column
156 maths::Vector<3,double>(0.0, sine, cose)
161 * Accessors
164 /// Get the longitude.
165 tcGeoAngle lon() const
167 return m_longitude;
169 /// Get the azimuth (longitude).
170 tcGeoAngle azim() const
172 return m_longitude;
175 /// Get the latitude.
176 tcGeoAngle lat() const
178 return m_latitude;
180 /// Get the elevation (latitude).
181 tcGeoAngle elev() const
183 return m_latitude;
186 /// Get a textual description.
187 QString describe() const
189 tcGeoAngleDMS dmsLon(m_longitude, false);
190 tcGeoAngleDMS dmsLat(m_latitude, true);
191 return QString("%1 %2").arg(dmsLat).arg(dmsLon);
195 * Mutators
198 /// Set the longitude.
199 void setLon(const tcGeoAngle lon)
201 m_longitude = lon;
203 /// Set the azimuth (longitude).
204 void setAzim(const tcGeoAngle lon)
206 m_longitude = lon;
209 /// Set the latitude.
210 void setLat(const tcGeoAngle lat)
212 m_latitude = lat;
214 /// Set the elevation (latitude).
215 void setElev(const tcGeoAngle lat)
217 m_latitude = lat;
220 /// Set the longitude and latitude.
221 void setLonLat(const tcGeoAngle lon, const tcGeoAngle lat)
223 m_longitude = lon;
224 m_latitude = lat;
226 /// Set the azimuth (longitude) and elevation (latitude).
227 void setAzimElev(const tcGeoAngle lon, const tcGeoAngle lat)
229 m_longitude = lon;
230 m_latitude = lat;
234 * Operators
237 tcGeo operator + (const tcGeo& other) const
239 return tcGeo(m_longitude + other.m_longitude,
240 m_latitude + other.m_latitude);
242 tcGeo operator - (const tcGeo& other) const
244 return tcGeo(m_longitude - other.m_longitude,
245 m_latitude - other.m_latitude);
247 tcGeo operator * (const tcGeoAngle factor) const
249 return tcGeo(m_longitude * factor,
250 m_latitude * factor);
252 tcGeo operator / (const tcGeoAngle factor) const
254 return tcGeo(m_longitude / factor,
255 m_latitude / factor);
257 maths::Vector<2,double> operator / (const tcGeo& other) const
259 return maths::Vector<2,double>(m_longitude / other.m_longitude,
260 m_latitude / other.m_latitude);
262 tcGeo operator * (const maths::Vector<2,double>& other) const
264 return tcGeo(m_longitude * other[0],
265 m_latitude * other[1]);
267 float angle() const
269 return sqrt(m_longitude*m_longitude + m_latitude*m_latitude);
272 private:
275 * Variables
278 /** East-West geographical coordinate.
279 * Units are radians.
281 tcGeoAngle m_longitude;
283 /** North-South geographical coordinate.
284 * Units are radians.
286 tcGeoAngle m_latitude;
290 #endif // _tcGeo_h_