]> git.mxchange.org Git - simgear.git/blob - Math/point3d.hxx
Optimizations from Norman Vine.
[simgear.git] / 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 // (Log is kept at end of this file)
23
24
25 #ifndef _POINT3D_HXX
26 #define _POINT3D_HXX
27
28
29 #ifndef __cplusplus                                                          
30 # error This library requires C++
31 #endif                                   
32
33 #include "Include/compiler.h"
34
35 #ifdef FG_MATH_EXCEPTION_CLASH
36 # define exception c_exception
37 #endif
38
39 #ifdef FG_HAVE_STD_INCLUDES
40 # include <iostream>
41 # include <cassert>
42 # include <cmath>
43 #else
44 # include <iostream.h>
45 # include <assert.h>
46 # include <math.h>
47 #endif
48
49 FG_USING_STD(ostream);
50 FG_USING_STD(istream);
51
52 // -rp- assert.h is buggy under MWCWP3, as multiple #include undef assert !
53 #ifdef __MWERKS__
54 #  define assert(x)
55 #endif
56
57 const double fgPoint3_Epsilon = 0.0000001;
58
59 enum {PX, PY, PZ};                  // axes
60
61 // Kludge for msvc++ 6.0 - requires forward decls of friend functions.
62 class Point3D;
63 istream& operator>> ( istream&, Point3D& );
64 ostream& operator<< ( ostream&, const Point3D& );
65 Point3D operator- (const Point3D& p);               // -p1
66 bool operator== (const Point3D& a, const Point3D& b);  // p1 == p2?
67
68
69 ///////////////////////////
70 //
71 // 3D Point
72 //
73 ///////////////////////////
74
75 class Point3D {
76
77 protected:
78
79     double n[3];
80
81 public:
82
83     // Constructors
84
85     Point3D();
86     Point3D(const double x, const double y, const double z);
87     explicit Point3D(const double d);
88     Point3D(const Point3D &p);
89
90     // Assignment operators
91
92     Point3D& operator = ( const Point3D& p );    // assignment of a Point3D
93     Point3D& operator += ( const Point3D& p );   // incrementation by a Point3D
94     Point3D& operator -= ( const Point3D& p );   // decrementation by a Point3D
95     Point3D& operator *= ( const double d );     // multiplication by a constant
96     Point3D& operator /= ( const double d );     // division by a constant
97
98     void setx(const double x);
99     void sety(const double y);
100     void setz(const double z);
101
102     // Queries 
103
104     double& operator [] ( int i);                // indexing
105     double operator[] (int i) const;             // read-only indexing
106
107     double x() const;      // cartesian x
108     double y() const;      // cartesian y
109     double z() const;      // cartesian z
110
111     double lon() const;    // polar longitude
112     double lat() const;    // polar latitude
113     double radius() const; // polar radius
114     double elev() const;   // geodetic elevation (if specifying a surface point)
115
116     // friends
117     friend Point3D operator - (const Point3D& p);                   // -p1
118     friend bool operator == (const Point3D& a, const Point3D& b);  // p1 == p2?
119     friend istream& operator>> ( istream&, Point3D& );
120     friend ostream& operator<< ( ostream&, const Point3D& );
121
122     // Special functions
123     double distance3D(const Point3D& a) const;        // distance between
124     double distance3Dsquared(const Point3D& a) const; // distance between ^ 2
125 };
126
127
128 // input from stream
129 inline istream&
130 operator >> ( istream& in, Point3D& p)
131 {
132     char c;
133
134     in >> p.n[PX];
135
136     // read past optional comma
137     while ( in.get(c) ) {
138         if ( (c != ' ') && (c != ',') ) {
139             // push back on the stream
140             in.putback(c);
141             break;
142         }
143     }
144         
145     in >> p.n[PY];
146
147     // read past optional comma
148     while ( in.get(c) ) {
149         if ( (c != ' ') && (c != ',') ) {
150             // push back on the stream
151             in.putback(c);
152             break;
153         }
154     }
155         
156     in >> p.n[PZ];
157
158     return in;
159 }
160
161 inline ostream&
162 operator<< ( ostream& out, const Point3D& p )
163 {
164     return out << p.n[PX] << ", " << p.n[PY] << ", " << p.n[PZ];
165 }
166
167 ///////////////////////////
168 //
169 // Point3D Member functions
170 //
171 ///////////////////////////
172
173 // CONSTRUCTORS
174
175 inline Point3D::Point3D() {}
176
177 inline Point3D::Point3D(const double x, const double y, const double z)
178 {
179     n[PX] = x; n[PY] = y; n[PZ] = z;
180 }
181
182 inline Point3D::Point3D(const double d)
183 {
184     n[PX] = n[PY] = n[PZ] = d;
185 }
186
187 inline Point3D::Point3D(const Point3D& p)
188 {
189     n[PX] = p.n[PX]; n[PY] = p.n[PY]; n[PZ] = p.n[PZ];
190 }
191
192 // ASSIGNMENT OPERATORS
193
194 inline Point3D& Point3D::operator = (const Point3D& p)
195 {
196     n[PX] = p.n[PX]; n[PY] = p.n[PY]; n[PZ] = p.n[PZ]; return *this;
197 }
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 double d )
210 {
211     n[PX] *= d; n[PY] *= d; n[PZ] *= d; return *this;
212 }
213
214 inline Point3D& Point3D::operator /= ( const double d )
215 {
216     double d_inv = 1./d; n[PX] *= d_inv; n[PY] *= d_inv; n[PZ] *= d_inv;
217     return *this;
218 }
219
220 inline void Point3D::setx(const double x) {
221     n[PX] = x;
222 }
223
224 inline void Point3D::sety(const double y) {
225     n[PY] = y;
226 }
227
228 inline void Point3D::setz(const double z) {
229     n[PZ] = z;
230 }
231
232 // QUERIES
233
234 inline double& Point3D::operator [] ( int i)
235 {
236     assert(! (i < PX || i > PZ));
237     return n[i];
238 }
239
240 inline double Point3D::operator [] ( int i) const {
241     assert(! (i < PX || i > PZ));
242     return n[i];
243 }
244
245
246 inline double Point3D::x() const { return n[PX]; }
247
248 inline double Point3D::y() const { return n[PY]; }
249
250 inline double Point3D::z() const { return n[PZ]; }
251
252 inline double Point3D::lon() const { return n[PX]; }
253
254 inline double Point3D::lat() const { return n[PY]; }
255
256 inline double Point3D::radius() const { return n[PZ]; }
257
258 inline double Point3D::elev() const { return n[PZ]; }
259
260
261 // FRIENDS
262
263 inline Point3D operator - (const Point3D& a)
264 {
265     return Point3D(-a.n[PX],-a.n[PY],-a.n[PZ]);
266 }
267
268 inline Point3D operator + (const Point3D& a, const Point3D& b)
269 {
270     return Point3D(a) += b;
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 double d)
279 {
280     return Point3D(a) *= d;
281 }
282
283 inline Point3D operator * (const double d, const Point3D& a)
284 {
285     return a*d;
286 }
287
288 inline Point3D operator / (const Point3D& a, const double d)
289 {
290     return Point3D(a) *= (1.0 / d );
291 }
292
293 inline bool operator == (const Point3D& a, const Point3D& b)
294 {
295     return
296         (a.n[PX] - b.n[PX]) < fgPoint3_Epsilon &&
297         (a.n[PY] - b.n[PY]) < fgPoint3_Epsilon &&
298         (a.n[PZ] - b.n[PZ]) < fgPoint3_Epsilon;
299 }
300
301 inline bool operator != (const Point3D& a, const Point3D& b)
302 {
303     return !(a == b);
304 }
305
306 // Special functions
307
308 inline double
309 Point3D::distance3D(const Point3D& a ) const
310 {
311     double x, y, z;
312
313     x = n[PX] - a.n[PX];
314     y = n[PY] - a.n[PY];
315     z = n[PZ] - a.n[PZ];
316
317     return sqrt(x*x + y*y + z*z);
318 }
319
320
321 inline double
322 Point3D::distance3Dsquared(const Point3D& a ) const
323 {
324     double x, y, z;
325
326     x = n[PX] - a.n[PX];
327     y = n[PY] - a.n[PY];
328     z = n[PZ] - a.n[PZ];
329
330     return(x*x + y*y + z*z);
331 }
332
333
334 #endif // _POINT3D_HXX
335
336
337 // $Log$
338 // Revision 1.9  1999/02/01 21:08:28  curt
339 // Optimizations from Norman Vine.
340 //
341 // Revision 1.8  1999/01/27 04:46:18  curt
342 // Portability tweaks by Bernie Bright.
343 //
344 // Revision 1.7  1999/01/19 20:56:58  curt
345 // MacOS portability changes contributed by "Robert Puyol" <puyol@abvent.fr>
346 //
347 // Revision 1.6  1998/11/23 21:46:37  curt
348 // Borland portability tweaks.
349 //
350 // Revision 1.5  1998/11/20 01:00:38  curt
351 // Patch in fgGeoc2Geod() to avoid a floating explosion.
352 // point3d.hxx include math.h for FreeBSD
353 //
354 // Revision 1.4  1998/11/11 00:18:38  curt
355 // Check for domain error in fgGeoctoGeod()
356 //
357 // Revision 1.3  1998/10/20 18:21:49  curt
358 // Tweaks from Bernie Bright.
359 //
360 // Revision 1.2  1998/10/18 01:17:12  curt
361 // Point3D tweaks.
362 //
363 // Revision 1.1  1998/10/16 00:50:29  curt
364 // Added point3d.hxx to replace cheezy fgPoint3d struct.
365 //
366 //