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 <input_output/FGPropertyManager.h>
61
static const char *IdSrc = "$Id: FGLocation.cpp,v 1.1 2006-01-12 15:04:22 ehofman Exp $";
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