1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5 Date started: 04/04/2004
6 Purpose: Store an arbitrary location on the globe
8 ------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) ------------------
9 ------- (C) 2004 Mathias Froehlich (Mathias.Froehlich@web.de) ----
11 This program is free software; you can redistribute it and/or modify it under
12 the terms of the GNU General Public License as published by the Free Software
13 Foundation; either version 2 of the License, or (at your option) any later
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
21 You should have received a copy of the GNU General Public License along with
22 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
23 Place - Suite 330, Boston, MA 02111-1307, USA.
25 Further information about the GNU General Public License can also be found on
26 the world wide web at http://www.gnu.org.
28 FUNCTIONAL DESCRIPTION
29 ------------------------------------------------------------------------------
30 This class encapsulates an arbitrary position in the globe with its accessors.
31 It has vector properties, so you can add multiply ....
34 ------------------------------------------------------------------------------
37 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
39 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
42 # include <simgear/compiler.h>
43 # ifdef SG_HAVE_STD_INCLUDES
49 # if defined(sgi) && !defined(__GNUC__)
56 #include "FGLocation.h"
57 #include "FGPropertyManager.h"
61 static const char *IdSrc = "$Id$";
62 static const char *IdHdr = ID_LOCATION;
64 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
66 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
68 FGLocation::FGLocation(double lon, double lat, double radius)
72 double sinLat = sin(lat);
73 double cosLat = cos(lat);
74 double sinLon = sin(lon);
75 double cosLon = cos(lon);
76 mECLoc = FGColumnVector3( radius*cosLat*cosLon,
81 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
83 void FGLocation::SetLongitude(double longitude)
85 double rtmp = mECLoc.Magnitude(eX, eY);
86 // Check if we have zero radius.
87 // If so set it to 1, so that we can set a position
88 if (0.0 == mECLoc.Magnitude())
91 // Fast return if we are on the north or south pole ...
97 mECLoc(eX) = rtmp*cos(longitude);
98 mECLoc(eY) = rtmp*sin(longitude);
101 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
103 void FGLocation::SetLatitude(double latitude)
107 double r = mECLoc.Magnitude();
113 double rtmp = mECLoc.Magnitude(eX, eY);
115 double fac = r/rtmp*cos(latitude);
119 mECLoc(eX) = r*cos(latitude);
122 mECLoc(eZ) = r*sin(latitude);
125 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
127 void FGLocation::SetRadius(double radius)
131 double rold = mECLoc.Magnitude();
135 mECLoc *= radius/rold;
138 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
140 void FGLocation::ComputeDerivedUnconditional(void) const
142 // The radius is just the Euclidean norm of the vector.
143 mRadius = mECLoc.Magnitude();
145 // The distance of the location to the y-axis, which is the axis
146 // through the poles.
147 double rxy = sqrt(mECLoc(eX)*mECLoc(eX) + mECLoc(eY)*mECLoc(eY));
149 // Compute the sin/cos values of the longitude
150 double sinLon, cosLon;
155 sinLon = mECLoc(eY)/rxy;
156 cosLon = mECLoc(eX)/rxy;
159 // Compute the sin/cos values of the latitude
160 double sinLat, cosLat;
161 if (mRadius == 0.0) {
165 sinLat = mECLoc(eZ)/mRadius;
166 cosLat = rxy/mRadius;
169 // Compute the longitude and latitude itself
170 if ( mECLoc( eX ) == 0.0 && mECLoc( eY ) == 0.0 )
173 mLon = atan2( mECLoc( eY ), mECLoc( eX ) );
175 if ( rxy == 0.0 && mECLoc( eZ ) == 0.0 )
178 mLat = atan2( mECLoc(eZ), rxy );
180 // Compute the transform matrices from and to the earth centered frame.
181 // see Durham Chapter 4, problem 1, page 52
182 mTec2l = FGMatrix33( -cosLon*sinLat, -sinLon*sinLat, cosLat,
183 -sinLon , cosLon , 0.0 ,
184 -cosLon*cosLat, -sinLon*cosLat, -sinLat );
186 mTl2ec = mTec2l.Transposed();
188 // Mark the cached values as valid
192 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
194 void FGLocation::bind(FGPropertyManager* PropertyManager, const string& prefix) const
196 PropertyManager->Tie(prefix + "lat-gc-rad", (FGLocation*)this,
197 &FGLocation::GetLatitude);
198 PropertyManager->Tie(prefix + "lat-gc-deg", (FGLocation*)this,
199 &FGLocation::GetLatitudeDeg);
200 PropertyManager->Tie(prefix + "long-gc-rad", (FGLocation*)this,
201 &FGLocation::GetLongitude);
202 PropertyManager->Tie(prefix + "long-gc-deg", (FGLocation*)this,
203 &FGLocation::GetLongitudeDeg);
204 PropertyManager->Tie(prefix + "radius-ft", (FGLocation*)this,
205 &FGLocation::GetRadius);
208 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
210 void FGLocation::unbind(FGPropertyManager* PropertyManager, const string& prefix) const
212 PropertyManager->Untie(prefix + "lat-gc-rad");
213 PropertyManager->Untie(prefix + "lat-gc-deg");
214 PropertyManager->Untie(prefix + "long-gc-rad");
215 PropertyManager->Untie(prefix + "long-gc-deg");
216 PropertyManager->Untie(prefix + "radius-ft");
219 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
221 } // namespace JSBSim