00001
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef _POINT3D_HXX
00031 #define _POINT3D_HXX
00032
00033
00034 #ifndef __cplusplus
00035 # error This library requires C++
00036 #endif
00037
00038 #include <simgear/compiler.h>
00039
00040 #include <ostream>
00041 #include <istream>
00042 #include <cassert>
00043 #include <cmath>
00044
00045 #include "SGMath.hxx"
00046
00047 const double fgPoint3_Epsilon = 0.0000001;
00048
00049 enum {PX, PY, PZ};
00050
00051
00052 class Point3D;
00053 std::istream& operator>> ( std::istream&, Point3D& );
00054 std::ostream& operator<< ( std::ostream&, const Point3D& );
00055 Point3D operator- (const Point3D& p);
00056 bool operator== (const Point3D& a, const Point3D& b);
00057
00058
00063 class Point3D {
00064
00065 protected:
00066
00067 double n[3];
00068
00069 public:
00070
00072 Point3D();
00073 Point3D(const double x, const double y, const double z);
00074 explicit Point3D(const double d);
00075 Point3D(const Point3D &p);
00076
00077 static Point3D fromSGGeod(const SGGeod& geod);
00078 static Point3D fromSGGeoc(const SGGeoc& geoc);
00079 static Point3D fromSGVec3(const SGVec3<double>& cart);
00080 static Point3D fromSGVec3(const SGVec3<float>& cart);
00081 static Point3D fromSGVec2(const SGVec2<double>& cart);
00082
00083
00084
00085 Point3D& operator = ( const Point3D& p );
00086 Point3D& operator += ( const Point3D& p );
00087 Point3D& operator -= ( const Point3D& p );
00088 Point3D& operator *= ( const double d );
00089 Point3D& operator /= ( const double d );
00090
00091 void setx(const double x);
00092 void sety(const double y);
00093 void setz(const double z);
00094 void setlon(const double x);
00095 void setlat(const double y);
00096 void setradius(const double z);
00097 void setelev(const double z);
00098
00099
00100
00101 double& operator [] ( int i);
00102 double operator[] (int i) const;
00103
00104 inline const double *get_n() const { return n; };
00105 double x() const;
00106 double y() const;
00107 double z() const;
00108
00109 double lon() const;
00110 double lat() const;
00111 double radius() const;
00112 double elev() const;
00113
00114 SGGeod toSGGeod(void) const;
00115 SGGeoc toSGGeoc(void) const;
00116
00117 SGVec3d toSGVec3d(void) const;
00118 SGVec3f toSGVec3f(void) const;
00119 SGVec2f toSGVec2f(void) const;
00120
00121
00122 friend Point3D operator - (const Point3D& p);
00123 friend bool operator == (const Point3D& a, const Point3D& b);
00124 friend std::istream& operator>> ( std::istream&, Point3D& );
00125 friend std::ostream& operator<< ( std::ostream&, const Point3D& );
00126
00127
00128 double distance3D(const Point3D& a) const;
00129 double distance3Dsquared(const Point3D& a) const;
00130 };
00131
00132
00133
00134 inline std::istream&
00135 operator >> ( std::istream& in, Point3D& p)
00136 {
00137 char c;
00138
00139 in >> p.n[PX];
00140
00141
00142 while ( in.get(c) ) {
00143 if ( (c != ' ') && (c != ',') ) {
00144
00145 in.putback(c);
00146 break;
00147 }
00148 }
00149
00150 in >> p.n[PY];
00151
00152
00153 while ( in.get(c) ) {
00154 if ( (c != ' ') && (c != ',') ) {
00155
00156 in.putback(c);
00157 break;
00158 }
00159 }
00160
00161 in >> p.n[PZ];
00162
00163 return in;
00164 }
00165
00166 inline std::ostream&
00167 operator<< ( std::ostream& out, const Point3D& p )
00168 {
00169 return out << p.n[PX] << ", " << p.n[PY] << ", " << p.n[PZ];
00170 }
00171
00173
00174
00175
00177
00178
00179
00180 inline Point3D::Point3D()
00181 {
00182 n[PX] = n[PY] = 0.0;
00183 n[PZ] = -9999.0;
00184 }
00185
00186 inline Point3D::Point3D(const double x, const double y, const double z)
00187 {
00188 n[PX] = x; n[PY] = y; n[PZ] = z;
00189 }
00190
00191 inline Point3D::Point3D(const double d)
00192 {
00193 n[PX] = n[PY] = n[PZ] = d;
00194 }
00195
00196 inline Point3D::Point3D(const Point3D& p)
00197 {
00198 n[PX] = p.n[PX]; n[PY] = p.n[PY]; n[PZ] = p.n[PZ];
00199 }
00200
00201 inline Point3D Point3D::fromSGGeod(const SGGeod& geod)
00202 {
00203 Point3D pt;
00204 pt.setlon(geod.getLongitudeRad());
00205 pt.setlat(geod.getLatitudeRad());
00206 pt.setelev(geod.getElevationM());
00207 return pt;
00208 }
00209
00210 inline Point3D Point3D::fromSGGeoc(const SGGeoc& geoc)
00211 {
00212 Point3D pt;
00213 pt.setlon(geoc.getLongitudeRad());
00214 pt.setlat(geoc.getLatitudeRad());
00215 pt.setradius(geoc.getRadiusM());
00216 return pt;
00217 }
00218
00219 inline Point3D Point3D::fromSGVec3(const SGVec3<double>& cart)
00220 {
00221 Point3D pt;
00222 pt.setx(cart.x());
00223 pt.sety(cart.y());
00224 pt.setz(cart.z());
00225 return pt;
00226 }
00227
00228 inline Point3D Point3D::fromSGVec3(const SGVec3<float>& cart)
00229 {
00230 Point3D pt;
00231 pt.setx(cart.x());
00232 pt.sety(cart.y());
00233 pt.setz(cart.z());
00234 return pt;
00235 }
00236
00237 inline Point3D Point3D::fromSGVec2(const SGVec2<double>& cart)
00238 {
00239 Point3D pt;
00240 pt.setx(cart.x());
00241 pt.sety(cart.y());
00242 pt.setz(0);
00243 return pt;
00244 }
00245
00246
00247
00248 inline Point3D& Point3D::operator = (const Point3D& p)
00249 {
00250 n[PX] = p.n[PX]; n[PY] = p.n[PY]; n[PZ] = p.n[PZ]; return *this;
00251 }
00252
00253 inline Point3D& Point3D::operator += ( const Point3D& p )
00254 {
00255 n[PX] += p.n[PX]; n[PY] += p.n[PY]; n[PZ] += p.n[PZ]; return *this;
00256 }
00257
00258 inline Point3D& Point3D::operator -= ( const Point3D& p )
00259 {
00260 n[PX] -= p.n[PX]; n[PY] -= p.n[PY]; n[PZ] -= p.n[PZ]; return *this;
00261 }
00262
00263 inline Point3D& Point3D::operator *= ( const double d )
00264 {
00265 n[PX] *= d; n[PY] *= d; n[PZ] *= d; return *this;
00266 }
00267
00268 inline Point3D& Point3D::operator /= ( const double d )
00269 {
00270 double d_inv = 1./d; n[PX] *= d_inv; n[PY] *= d_inv; n[PZ] *= d_inv;
00271 return *this;
00272 }
00273
00274 inline void Point3D::setx(const double x) {
00275 n[PX] = x;
00276 }
00277
00278 inline void Point3D::sety(const double y) {
00279 n[PY] = y;
00280 }
00281
00282 inline void Point3D::setz(const double z) {
00283 n[PZ] = z;
00284 }
00285
00286 inline void Point3D::setlon(const double x) {
00287 n[PX] = x;
00288 }
00289
00290 inline void Point3D::setlat(const double y) {
00291 n[PY] = y;
00292 }
00293
00294 inline void Point3D::setradius(const double z) {
00295 n[PZ] = z;
00296 }
00297
00298 inline void Point3D::setelev(const double z) {
00299 n[PZ] = z;
00300 }
00301
00302
00303
00304 inline double& Point3D::operator [] ( int i)
00305 {
00306 assert(! (i < PX || i > PZ));
00307 return n[i];
00308 }
00309
00310 inline double Point3D::operator [] ( int i) const {
00311 assert(! (i < PX || i > PZ));
00312 return n[i];
00313 }
00314
00315
00316 inline double Point3D::x() const { return n[PX]; }
00317
00318 inline double Point3D::y() const { return n[PY]; }
00319
00320 inline double Point3D::z() const { return n[PZ]; }
00321
00322 inline double Point3D::lon() const { return n[PX]; }
00323
00324 inline double Point3D::lat() const { return n[PY]; }
00325
00326 inline double Point3D::radius() const { return n[PZ]; }
00327
00328 inline double Point3D::elev() const { return n[PZ]; }
00329
00330 inline SGGeod Point3D::toSGGeod(void) const
00331 {
00332 SGGeod geod;
00333 geod.setLongitudeRad(lon());
00334 geod.setLatitudeRad(lat());
00335 geod.setElevationM(elev());
00336 return geod;
00337 }
00338
00339 inline SGGeoc Point3D::toSGGeoc(void) const
00340 {
00341 SGGeoc geoc;
00342 geoc.setLongitudeRad(lon());
00343 geoc.setLatitudeRad(lat());
00344 geoc.setRadiusM(radius());
00345 return geoc;
00346 }
00347
00348 inline SGVec3d Point3D::toSGVec3d(void) const
00349 {
00350 return SGVec3d(x(), y(), z());
00351 }
00352
00353 inline SGVec3f Point3D::toSGVec3f(void) const
00354 {
00355 return SGVec3f(x(), y(), z());
00356 }
00357
00358 inline SGVec2f Point3D::toSGVec2f(void) const
00359 {
00360 return SGVec2f(x(), y());
00361 }
00362
00363
00364
00365 inline Point3D operator - (const Point3D& a)
00366 {
00367 return Point3D(-a.n[PX],-a.n[PY],-a.n[PZ]);
00368 }
00369
00370 inline Point3D operator + (const Point3D& a, const Point3D& b)
00371 {
00372 return Point3D(a) += b;
00373 }
00374
00375 inline Point3D operator - (const Point3D& a, const Point3D& b)
00376 {
00377 return Point3D(a) -= b;
00378 }
00379
00380 inline Point3D operator * (const Point3D& a, const double d)
00381 {
00382 return Point3D(a) *= d;
00383 }
00384
00385 inline Point3D operator * (const double d, const Point3D& a)
00386 {
00387 return a*d;
00388 }
00389
00390 inline Point3D operator / (const Point3D& a, const double d)
00391 {
00392 return Point3D(a) *= (1.0 / d );
00393 }
00394
00395 inline bool operator == (const Point3D& a, const Point3D& b)
00396 {
00397 return
00398 fabs(a.n[PX] - b.n[PX]) < fgPoint3_Epsilon &&
00399 fabs(a.n[PY] - b.n[PY]) < fgPoint3_Epsilon &&
00400 fabs(a.n[PZ] - b.n[PZ]) < fgPoint3_Epsilon;
00401 }
00402
00403 inline bool operator != (const Point3D& a, const Point3D& b)
00404 {
00405 return !(a == b);
00406 }
00407
00408
00409
00410 inline double
00411 Point3D::distance3D(const Point3D& a ) const
00412 {
00413 double x, y, z;
00414
00415 x = n[PX] - a.n[PX];
00416 y = n[PY] - a.n[PY];
00417 z = n[PZ] - a.n[PZ];
00418
00419 return sqrt(x*x + y*y + z*z);
00420 }
00421
00422
00423 inline double
00424 Point3D::distance3Dsquared(const Point3D& a ) const
00425 {
00426 double x, y, z;
00427
00428 x = n[PX] - a.n[PX];
00429 y = n[PY] - a.n[PY];
00430 z = n[PZ] - a.n[PZ];
00431
00432 return(x*x + y*y + z*z);
00433 }
00434
00435
00436 #endif // _POINT3D_HXX
00437
00438