Added gui options for wireframe, and colour coding
[tecorrec.git] / geo / tcGeo.h
blobb4bae1f3e643d9b338dfbb5c77029357afe52efd
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,double> () const
119 //return this->operator maths::Matrix<3,double>() * maths::Vector<3,double>(0.0, 0.0, 1.0);
120 double z = sin(m_latitude);
121 double xy = cos(m_latitude);
122 return maths::Vector<3,double>(xy*sin(m_longitude), -xy*cos(m_longitude), z);
125 /// Convert to a rotation matrix.
126 operator maths::Matrix<3,double> () const
128 return maths::Matrix<3,double>(
129 maths::RotateRadMatrix44('x', m_latitude-M_PI/2)
131 maths::RotateRadMatrix44('z', -m_longitude)
133 double sina = sin(m_longitude);
134 double cosa = cos(m_longitude);
135 double sine = sin(m_latitude-M_PI/2);
136 double cose = cos(m_latitude-M_PI/2);
138 [[cos(a), sin(a), 0],
139 [-sin(a) cos(-1/2 PI+e),cos(a) cos(-1/2 PI+e), sin(-1/2 PI+e)],
140 [sin(a) sin(-1/2 PI+e), -cos(a) sin(-1/2 PI+e),cos(-1/2 PI+e)]]
142 return maths::Matrix<3,double>(
143 // First column
144 maths::Vector<3,double>(cosa, -sina*cose, sina*sine),
145 // Second column
146 maths::Vector<3,double>(sina, cosa*cose, -cosa*sine),
147 // Third column
148 maths::Vector<3,double>(0.0, sine, cose)
153 * Accessors
156 /// Get the longitude.
157 tcGeoAngle lon() const
159 return m_longitude;
161 /// Get the azimuth (longitude).
162 tcGeoAngle azim() const
164 return m_longitude;
167 /// Get the latitude.
168 tcGeoAngle lat() const
170 return m_latitude;
172 /// Get the elevation (latitude).
173 tcGeoAngle elev() const
175 return m_latitude;
178 /// Get a textual description.
179 QString describe() const
181 tcGeoAngleDMS dmsLon(m_longitude, false);
182 tcGeoAngleDMS dmsLat(m_latitude, true);
183 return QString("%1 %2").arg(dmsLat).arg(dmsLon);
187 * Mutators
190 /// Set the longitude.
191 void setLon(const tcGeoAngle lon)
193 m_longitude = lon;
195 /// Set the azimuth (longitude).
196 void setAzim(const tcGeoAngle lon)
198 m_longitude = lon;
201 /// Set the latitude.
202 void setLat(const tcGeoAngle lat)
204 m_latitude = lat;
206 /// Set the elevation (latitude).
207 void setElev(const tcGeoAngle lat)
209 m_latitude = lat;
212 /// Set the longitude and latitude.
213 void setLonLat(const tcGeoAngle lon, const tcGeoAngle lat)
215 m_longitude = lon;
216 m_latitude = lat;
218 /// Set the azimuth (longitude) and elevation (latitude).
219 void setAzimElev(const tcGeoAngle lon, const tcGeoAngle lat)
221 m_longitude = lon;
222 m_latitude = lat;
226 * Operators
229 tcGeo operator + (const tcGeo& other) const
231 return tcGeo(m_longitude + other.m_longitude,
232 m_latitude + other.m_latitude);
234 tcGeo operator - (const tcGeo& other) const
236 return tcGeo(m_longitude - other.m_longitude,
237 m_latitude - other.m_latitude);
239 tcGeo operator * (const tcGeoAngle factor) const
241 return tcGeo(m_longitude * factor,
242 m_latitude * factor);
244 tcGeo operator / (const tcGeoAngle factor) const
246 return tcGeo(m_longitude / factor,
247 m_latitude / factor);
249 maths::Vector<2,double> operator / (const tcGeo& other) const
251 return maths::Vector<2,double>(m_longitude / other.m_longitude,
252 m_latitude / other.m_latitude);
254 tcGeo operator * (const maths::Vector<2,double>& other) const
256 return tcGeo(m_longitude * other[0],
257 m_latitude * other[1]);
260 private:
263 * Variables
266 /** East-West geographical coordinate.
267 * Units are radians.
269 tcGeoAngle m_longitude;
271 /** North-South geographical coordinate.
272 * Units are radians.
274 tcGeoAngle m_latitude;
278 #endif // _tcGeo_h_