OSG  3.4.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
CoordinateSystemNode.h
Go to the documentation of this file.
1 /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2  *
3  * This library is open source and may be redistributed and/or modified under
4  * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5  * (at your option) any later version. The full license is in LICENSE file
6  * included with this distribution, and on the openscenegraph.org website.
7  *
8  * This library is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * OpenSceneGraph Public License for more details.
12 */
13 
14 #ifndef OSG_COORDINATESYSTEMNODE
15 #define OSG_COORDINATESYSTEMNODE 1
16 
17 #include <osg/Group>
18 #include <osg/Matrixd>
19 
20 namespace osg
21 {
22 
23 const double WGS_84_RADIUS_EQUATOR = 6378137.0;
24 const double WGS_84_RADIUS_POLAR = 6356752.3142;
25 
30 class EllipsoidModel : public Object
31 {
32  public:
33 
35  EllipsoidModel(double radiusEquator = WGS_84_RADIUS_EQUATOR,
36  double radiusPolar = WGS_84_RADIUS_POLAR):
37  _radiusEquator(radiusEquator),
38  _radiusPolar(radiusPolar) { computeCoefficients(); }
39 
41  Object(et,copyop),
44 
46 
47  void setRadiusEquator(double radius) { _radiusEquator = radius; computeCoefficients(); }
48  double getRadiusEquator() const { return _radiusEquator; }
49 
50  void setRadiusPolar(double radius) { _radiusPolar = radius; computeCoefficients(); }
51  double getRadiusPolar() const { return _radiusPolar; }
52 
53  inline void convertLatLongHeightToXYZ(double latitude, double longitude, double height,
54  double& X, double& Y, double& Z) const;
55 
56  inline void convertXYZToLatLongHeight(double X, double Y, double Z,
57  double& latitude, double& longitude, double& height) const;
58 
59  inline void computeLocalToWorldTransformFromLatLongHeight(double latitude, double longitude, double height, osg::Matrixd& localToWorld) const;
60 
61  inline void computeLocalToWorldTransformFromXYZ(double X, double Y, double Z, osg::Matrixd& localToWorld) const;
62 
63  inline void computeCoordinateFrame(double latitude, double longitude, osg::Matrixd& localToWorld) const;
64 
65  inline osg::Vec3d computeLocalUpVector(double X, double Y, double Z) const;
66 
67  // Convenience method for determining if EllipsoidModel is a stock WGS84 ellipsoid
68  inline bool isWGS84() const {return(_radiusEquator == WGS_84_RADIUS_EQUATOR && _radiusPolar == WGS_84_RADIUS_POLAR);}
69 
70  // Compares two EllipsoidModel by comparing critical internal values.
71  // Ignores _eccentricitySquared since it's just a cached value derived from
72  // the _radiusEquator and _radiusPolar members.
73  friend bool operator == ( const EllipsoidModel & e1, const EllipsoidModel& e2) {return(e1._radiusEquator == e2._radiusEquator && e1._radiusPolar == e2._radiusPolar);}
74 
75 
76  protected:
77 
79  {
80  double flattening = (_radiusEquator-_radiusPolar)/_radiusEquator;
81  _eccentricitySquared = 2*flattening - flattening*flattening;
82  }
83 
85  double _radiusPolar;
87 
88 };
89 
92 
96 {
97  public:
98 
100 
101  CoordinateSystemNode(const std::string& format, const std::string& cs);
102 
105 
107 
108 
110  void set(const CoordinateSystemNode& csn);
111 
113  void setFormat(const std::string& format) { _format = format; }
114 
116  const std::string& getFormat() const { return _format; }
117 
119  void setCoordinateSystem(const std::string& cs) { _cs = cs; }
120 
122  const std::string& getCoordinateSystem() const { return _cs; }
123 
124 
126  void setEllipsoidModel(EllipsoidModel* ellipsode) { _ellipsoidModel = ellipsode; }
127 
129  EllipsoidModel* getEllipsoidModel() { return _ellipsoidModel.get(); }
130 
132  const EllipsoidModel* getEllipsoidModel() const { return _ellipsoidModel.get(); }
133 
135  CoordinateFrame computeLocalCoordinateFrame(const Vec3d& position) const;
136 
138  osg::Vec3d computeLocalUpVector(const Vec3d& position) const;
139 
140  protected:
141 
143 
144  std::string _format;
145  std::string _cs;
147 
148 };
149 
150 
151 
153 // implement inline methods.
154 //
155 inline void EllipsoidModel::convertLatLongHeightToXYZ(double latitude, double longitude, double height,
156  double& X, double& Y, double& Z) const
157 {
158  // for details on maths see http://www.colorado.edu/geography/gcraft/notes/datum/gif/llhxyz.gif
159  double sin_latitude = sin(latitude);
160  double cos_latitude = cos(latitude);
161  double N = _radiusEquator / sqrt( 1.0 - _eccentricitySquared*sin_latitude*sin_latitude);
162  X = (N+height)*cos_latitude*cos(longitude);
163  Y = (N+height)*cos_latitude*sin(longitude);
164  Z = (N*(1-_eccentricitySquared)+height)*sin_latitude;
165 }
166 
167 
168 inline void EllipsoidModel::convertXYZToLatLongHeight(double X, double Y, double Z,
169  double& latitude, double& longitude, double& height) const
170 {
171  // http://www.colorado.edu/geography/gcraft/notes/datum/gif/xyzllh.gif
172  double p = sqrt(X*X + Y*Y);
173  double theta = atan2(Z*_radiusEquator , (p*_radiusPolar));
174  double eDashSquared = (_radiusEquator*_radiusEquator - _radiusPolar*_radiusPolar)/
175  (_radiusPolar*_radiusPolar);
176 
177  double sin_theta = sin(theta);
178  double cos_theta = cos(theta);
179 
180  latitude = atan( (Z + eDashSquared*_radiusPolar*sin_theta*sin_theta*sin_theta) /
181  (p - _eccentricitySquared*_radiusEquator*cos_theta*cos_theta*cos_theta) );
182  longitude = atan2(Y,X);
183 
184  double sin_latitude = sin(latitude);
185  double N = _radiusEquator / sqrt( 1.0 - _eccentricitySquared*sin_latitude*sin_latitude);
186 
187  height = p/cos(latitude) - N;
188 }
189 
190 inline void EllipsoidModel::computeLocalToWorldTransformFromLatLongHeight(double latitude, double longitude, double height, osg::Matrixd& localToWorld) const
191 {
192  double X, Y, Z;
193  convertLatLongHeightToXYZ(latitude,longitude,height,X,Y,Z);
194 
195  localToWorld.makeTranslate(X,Y,Z);
196  computeCoordinateFrame(latitude, longitude, localToWorld);
197 }
198 
199 inline void EllipsoidModel::computeLocalToWorldTransformFromXYZ(double X, double Y, double Z, osg::Matrixd& localToWorld) const
200 {
201  double latitude, longitude, height;
202  convertXYZToLatLongHeight(X,Y,Z,latitude,longitude,height);
203 
204  localToWorld.makeTranslate(X,Y,Z);
205  computeCoordinateFrame(latitude, longitude, localToWorld);
206 }
207 
208 inline void EllipsoidModel::computeCoordinateFrame(double latitude, double longitude, osg::Matrixd& localToWorld) const
209 {
210  // Compute up vector
211  osg::Vec3d up ( cos(longitude)*cos(latitude), sin(longitude)*cos(latitude), sin(latitude));
212 
213  // Compute east vector
214  osg::Vec3d east (-sin(longitude), cos(longitude), 0);
215 
216  // Compute north vector = outer product up x east
217  osg::Vec3d north = up ^ east;
218 
219  // set matrix
220  localToWorld(0,0) = east[0];
221  localToWorld(0,1) = east[1];
222  localToWorld(0,2) = east[2];
223 
224  localToWorld(1,0) = north[0];
225  localToWorld(1,1) = north[1];
226  localToWorld(1,2) = north[2];
227 
228  localToWorld(2,0) = up[0];
229  localToWorld(2,1) = up[1];
230  localToWorld(2,2) = up[2];
231 }
232 
233 inline osg::Vec3d EllipsoidModel::computeLocalUpVector(double X, double Y, double Z) const
234 {
235  // Note latitude is angle between normal to ellipsoid surface and XY-plane
236  double latitude;
237  double longitude;
238  double altitude;
239  convertXYZToLatLongHeight(X,Y,Z,latitude,longitude,altitude);
240 
241  // Compute up vector
242  return osg::Vec3d( cos(longitude) * cos(latitude),
243  sin(longitude) * cos(latitude),
244  sin(latitude));
245 }
246 
247 }
248 #endif
void computeCoordinateFrame(double latitude, double longitude, osg::Matrixd &localToWorld) const
#define OSG_EXPORT
Definition: Export.h:43
EllipsoidModel(double radiusEquator=WGS_84_RADIUS_EQUATOR, double radiusPolar=WGS_84_RADIUS_POLAR)
void setEllipsoidModel(EllipsoidModel *ellipsode)
const std::string & getFormat() const
const std::string & getCoordinateSystem() const
const double WGS_84_RADIUS_POLAR
osg::Vec3d computeLocalUpVector(double X, double Y, double Z) const
void setRadiusPolar(double radius)
#define META_Node(library, name)
Definition: Node.h:59
const EllipsoidModel * getEllipsoidModel() const
ref_ptr< EllipsoidModel > _ellipsoidModel
void setRadiusEquator(double radius)
EllipsoidModel * getEllipsoidModel()
void computeLocalToWorldTransformFromXYZ(double X, double Y, double Z, osg::Matrixd &localToWorld) const
void convertXYZToLatLongHeight(double X, double Y, double Z, double &latitude, double &longitude, double &height) const
EllipsoidModel(const EllipsoidModel &et, const CopyOp &copyop=CopyOp::SHALLOW_COPY)
void setFormat(const std::string &format)
const double WGS_84_RADIUS_EQUATOR
GLint GLenum GLsizei GLsizei height
Definition: GLU.h:71
friend bool operator==(const EllipsoidModel &e1, const EllipsoidModel &e2)
Definition: AlphaFunc.h:19
META_Object(osg, EllipsoidModel)
void computeLocalToWorldTransformFromLatLongHeight(double latitude, double longitude, double height, osg::Matrixd &localToWorld) const
void makeTranslate(const Vec3f &)
void setCoordinateSystem(const std::string &cs)
Matrixd CoordinateFrame
double getRadiusPolar() const
double getRadiusEquator() const
void convertLatLongHeightToXYZ(double latitude, double longitude, double height, double &X, double &Y, double &Z) const
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum format
Definition: GLU.h:71