]> git.mxchange.org Git - simgear.git/blob - simgear/math/point3d.hxx
Added simgear/magvar which impliments WMM 2000 world magnetic variance model.
[simgear.git] / simgear / math / point3d.hxx
1 // point3d.hxx -- a 3d point class.  
2 //
3 // Adapted from algebra3 by Jean-Francois Doue, started October 1998.
4 //
5 // Copyright (C) 1998  Curtis L. Olson  - curt@me.umn.edu
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 // General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 //
21 // $Id$
22
23
24 #ifndef _POINT3D_HXX
25 #define _POINT3D_HXX
26
27
28 #ifndef __cplusplus                                                          
29 # error This library requires C++
30 #endif                                   
31
32 #include <simgear/compiler.h>
33
34 #ifdef FG_MATH_EXCEPTION_CLASH
35 # define exception c_exception
36 #endif
37
38 #ifdef FG_HAVE_STD_INCLUDES
39 # include <iostream>
40 # include <cassert>
41 # include <cmath>
42 #else
43 # include <iostream.h>
44 # include <assert.h>
45 # include <math.h>
46 #endif
47
48 // I don't understand ... <math.h> or <cmath> should be included
49 // already depending on how you defined FG_HAVE_STD_INCLUDES, but I
50 // can go ahead and add this -- CLO
51 #ifdef __MWERKS__
52 FG_USING_NAMESPACE(std);
53 #endif
54
55 #ifndef FG_HAVE_NATIVE_SGI_COMPILERS
56 FG_USING_STD(ostream);
57 FG_USING_STD(istream);
58 #endif
59
60
61 const double fgPoint3_Epsilon = 0.0000001;
62
63 enum {PX, PY, PZ};                  // axes
64
65 // Kludge for msvc++ 6.0 - requires forward decls of friend functions.
66 class Point3D;
67 istream& operator>> ( istream&, Point3D& );
68 ostream& operator<< ( ostream&, const Point3D& );
69 Point3D operator- (const Point3D& p);               // -p1
70 bool operator== (const Point3D& a, const Point3D& b);  // p1 == p2?
71
72
73 ///////////////////////////
74 //
75 // 3D Point
76 //
77 ///////////////////////////
78
79 class Point3D {
80
81 protected:
82
83     double n[3];
84
85 public:
86
87     // Constructors
88
89     Point3D();
90     Point3D(const double x, const double y, const double z);
91     explicit Point3D(const double d);
92     Point3D(const Point3D &p);
93
94     // Assignment operators
95
96     Point3D& operator = ( const Point3D& p );    // assignment of a Point3D
97     Point3D& operator += ( const Point3D& p );   // incrementation by a Point3D
98     Point3D& operator -= ( const Point3D& p );   // decrementation by a Point3D
99     Point3D& operator *= ( const double d );     // multiplication by a constant
100     Point3D& operator /= ( const double d );     // division by a constant
101
102     void setx(const double x);
103     void sety(const double y);
104     void setz(const double z);
105
106     // Queries 
107
108     double& operator [] ( int i);                // indexing
109     double operator[] (int i) const;             // read-only indexing
110
111     inline const double *get_n() const { return n; };
112     double x() const;      // cartesian x
113     double y() const;      // cartesian y
114     double z() const;      // cartesian z
115
116     double lon() const;    // polar longitude
117     double lat() const;    // polar latitude
118     double radius() const; // polar radius
119     double elev() const;   // geodetic elevation (if specifying a surface point)
120
121     // friends
122     friend Point3D operator - (const Point3D& p);                   // -p1
123     friend bool operator == (const Point3D& a, const Point3D& b);  // p1 == p2?
124     friend istream& operator>> ( istream&, Point3D& );
125     friend ostream& operator<< ( ostream&, const Point3D& );
126
127     // Special functions
128     double distance3D(const Point3D& a) const;        // distance between
129     double distance3Dsquared(const Point3D& a) const; // distance between ^ 2
130 };
131
132
133 // input from stream
134 inline istream&
135 operator >> ( istream& in, Point3D& p)
136 {
137     char c;
138
139     in >> p.n[PX];
140
141     // read past optional comma
142     while ( in.get(c) ) {
143         if ( (c != ' ') && (c != ',') ) {
144             // push back on the stream
145             in.putback(c);
146             break;
147         }
148     }
149         
150     in >> p.n[PY];
151
152     // read past optional comma
153     while ( in.get(c) ) {
154         if ( (c != ' ') && (c != ',') ) {
155             // push back on the stream
156             in.putback(c);
157             break;
158         }
159     }
160         
161     in >> p.n[PZ];
162
163     return in;
164 }
165
166 inline ostream&
167 operator<< ( ostream& out, const Point3D& p )
168 {
169     return out << p.n[PX] << ", " << p.n[PY] << ", " << p.n[PZ];
170 }
171
172 ///////////////////////////
173 //
174 // Point3D Member functions
175 //
176 ///////////////////////////
177
178 // CONSTRUCTORS
179
180 inline Point3D::Point3D() {}
181
182 inline Point3D::Point3D(const double x, const double y, const double z)
183 {
184     n[PX] = x; n[PY] = y; n[PZ] = z;
185 }
186
187 inline Point3D::Point3D(const double d)
188 {
189     n[PX] = n[PY] = n[PZ] = d;
190 }
191
192 inline Point3D::Point3D(const Point3D& p)
193 {
194     n[PX] = p.n[PX]; n[PY] = p.n[PY]; n[PZ] = p.n[PZ];
195 }
196
197 // ASSIGNMENT OPERATORS
198
199 inline Point3D& Point3D::operator = (const Point3D& p)
200 {
201     n[PX] = p.n[PX]; n[PY] = p.n[PY]; n[PZ] = p.n[PZ]; return *this;
202 }
203
204 inline Point3D& Point3D::operator += ( const Point3D& p )
205 {
206     n[PX] += p.n[PX]; n[PY] += p.n[PY]; n[PZ] += p.n[PZ]; return *this;
207 }
208
209 inline Point3D& Point3D::operator -= ( const Point3D& p )
210 {
211     n[PX] -= p.n[PX]; n[PY] -= p.n[PY]; n[PZ] -= p.n[PZ]; return *this;
212 }
213
214 inline Point3D& Point3D::operator *= ( const double d )
215 {
216     n[PX] *= d; n[PY] *= d; n[PZ] *= d; return *this;
217 }
218
219 inline Point3D& Point3D::operator /= ( const double d )
220 {
221     double d_inv = 1./d; n[PX] *= d_inv; n[PY] *= d_inv; n[PZ] *= d_inv;
222     return *this;
223 }
224
225 inline void Point3D::setx(const double x) {
226     n[PX] = x;
227 }
228
229 inline void Point3D::sety(const double y) {
230     n[PY] = y;
231 }
232
233 inline void Point3D::setz(const double z) {
234     n[PZ] = z;
235 }
236
237 // QUERIES
238
239 inline double& Point3D::operator [] ( int i)
240 {
241     assert(! (i < PX || i > PZ));
242     return n[i];
243 }
244
245 inline double Point3D::operator [] ( int i) const {
246     assert(! (i < PX || i > PZ));
247     return n[i];
248 }
249
250
251 inline double Point3D::x() const { return n[PX]; }
252
253 inline double Point3D::y() const { return n[PY]; }
254
255 inline double Point3D::z() const { return n[PZ]; }
256
257 inline double Point3D::lon() const { return n[PX]; }
258
259 inline double Point3D::lat() const { return n[PY]; }
260
261 inline double Point3D::radius() const { return n[PZ]; }
262
263 inline double Point3D::elev() const { return n[PZ]; }
264
265
266 // FRIENDS
267
268 inline Point3D operator - (const Point3D& a)
269 {
270     return Point3D(-a.n[PX],-a.n[PY],-a.n[PZ]);
271 }
272
273 inline Point3D operator + (const Point3D& a, const Point3D& b)
274 {
275     return Point3D(a) += b;
276 }
277
278 inline Point3D operator - (const Point3D& a, const Point3D& b)
279 {
280     return Point3D(a) -= b;
281 }
282
283 inline Point3D operator * (const Point3D& a, const double d)
284 {
285     return Point3D(a) *= d;
286 }
287
288 inline Point3D operator * (const double d, const Point3D& a)
289 {
290     return a*d;
291 }
292
293 inline Point3D operator / (const Point3D& a, const double d)
294 {
295     return Point3D(a) *= (1.0 / d );
296 }
297
298 inline bool operator == (const Point3D& a, const Point3D& b)
299 {
300     return
301         fabs(a.n[PX] - b.n[PX]) < fgPoint3_Epsilon &&
302         fabs(a.n[PY] - b.n[PY]) < fgPoint3_Epsilon &&
303         fabs(a.n[PZ] - b.n[PZ]) < fgPoint3_Epsilon;
304 }
305
306 inline bool operator != (const Point3D& a, const Point3D& b)
307 {
308     return !(a == b);
309 }
310
311 // Special functions
312
313 inline double
314 Point3D::distance3D(const Point3D& a ) const
315 {
316     double x, y, z;
317
318     x = n[PX] - a.n[PX];
319     y = n[PY] - a.n[PY];
320     z = n[PZ] - a.n[PZ];
321
322     return sqrt(x*x + y*y + z*z);
323 }
324
325
326 inline double
327 Point3D::distance3Dsquared(const Point3D& a ) const
328 {
329     double x, y, z;
330
331     x = n[PX] - a.n[PX];
332     y = n[PY] - a.n[PY];
333     z = n[PZ] - a.n[PZ];
334
335     return(x*x + y*y + z*z);
336 }
337
338
339 #endif // _POINT3D_HXX
340
341