point.h

Go to the documentation of this file.
00001 /**
00002  * \file point.h <mi32/point.h>
00003  * \brief Definitions for 2D and 3D point structures
00004  *
00005  * \if NODOC
00006  * $Id: point.h_v 1.53 2005/01/11 18:16:55 vdronov Exp $
00007  *
00008  * $Log: point.h_v $
00009  * Revision 1.53  2005/01/11 18:16:55  vdronov
00010  * added GetDistance and GetDistanceSquared from point to origin for DPOINT3D
00011  *
00012  * Revision 1.52  2004/11/16 17:14:03  dwilliss
00013  * Added a TruncateToLong method to DPOINT2D
00014  *
00015  * Revision 1.51  2004/09/02 14:42:49  scowan
00016  * Added more swap bytes external functions.
00017  *
00018  * Revision 1.50  2004/08/11 23:05:14  vdronov
00019  * *** empty log message ***
00020  *
00021  * Revision 1.49  2004/06/21 17:47:46  mju
00022  * Add Get/SetOrdinate to dpoint2d.
00023  *
00024  * Revision 1.48  2004/03/22 18:51:58  mju
00025  * Use double parms for DPOINT3DH instead of floata.
00026  *
00027  * Revision 1.47  2004/02/03 16:50:59  scowan
00028  * Added copy ctors for dpoint 3d and fpoint 3d.
00029  *
00030  * Revision 1.46  2003/09/25 21:29:07  dwilliss
00031  * Don't capitalize enum any more. Genitor needed it, doxygen doesn't like it.
00032  *
00033  * Revision 1.45  2003/09/23 17:56:05  dwilliss
00034  * Added a CrossProduct method to DPOINT3D
00035  *
00036  * Revision 1.44  2003/09/15 13:49:56  fileserver!dwilliss
00037  * Doxygen
00038  *
00039  * Revision 1.43  2003/08/14 19:48:35  vdronov
00040  * small changes.
00041  *
00042  * Revision 1.42  2003/02/21 15:20:00  mju
00043  * Add SwapBytes methods.
00044  * Change return-by-value operators to do computation and construction when return so may optimize better.
00045  *
00046  * Revision 1.41  2003/02/06 18:53:11  msmith
00047  * Added == and != to FPOINT2D and FPOINT3D
00048  *
00049  * Revision 1.40  2003/02/03 21:25:23  vdronov
00050  * added some const to FPOINT
00051  *
00052  * Revision 1.39  2003/02/03 20:32:35  vdronov
00053  * changed DotProduct and CrossProduct
00054  *
00055  * Revision 1.38  2003/01/27 16:31:35  vdronov
00056  * added some methods for FPOINT2D and FPOINT3D
00057  *
00058  * Revision 1.37  2003/01/24 23:41:47  vdronov
00059  * added some methods for FPOINT2d
00060  *
00061  * Revision 1.36  2003/01/24 23:34:53  vdronov
00062  * changed some parameters from by value to by reference for FPOINT2D and FPOINT3D
00063  *
00064  * Revision 1.35  2002/12/05 15:26:40  vdronov
00065  * fixed warnings
00066  *
00067  * Revision 1.34  2002/11/27 21:39:37  vdronov
00068  * FPOINT3DH
00069  *
00070  * Revision 1.33  2002/11/20 22:02:12  vdronov
00071  * class DPOINT3DH added
00072  *
00073  * Revision 1.32  2002/10/10 14:57:33  msmith
00074  * Added operators to FPOINT2D
00075  *
00076  * Revision 1.31  2002/08/12 22:59:36  vdronov
00077  * added operators for DPOINT3D
00078  *
00079  * Revision 1.29  2002/05/17 15:34:31  dwilliss
00080  * Don't leave dangling commas on the last item in an enum.  It makes the
00081  * Mac give a compiler warning, making it hard to find the real errors in
00082  * their poorly formatted error messages
00083  *
00084  * Revision 1.28  2002/02/19 15:36:12  scowan
00085  * More docs.
00086  *
00087  * Revision 1.27  2002/02/13 16:29:47  vdronov
00088  * added 2 methods to DPOINT2D
00089  *
00090  * Revision 1.26  2002/02/08 16:43:10  scowan
00091  * Uses round macro for better speed.
00092  *
00093  * Revision 1.25  2002/02/08 16:41:03  vdronov
00094  * added DPOINT2D operators
00095  *
00096  * Revision 1.24  2002/01/29 21:40:40  scowan
00097  * Added get angle.
00098  *
00099  * Revision 1.23  2001/12/20 21:34:35  mju
00100  * Enum docs.
00101  *
00102  * Revision 1.22  2001/12/11 16:22:55  scowan
00103  * Added swapping fpoint 2d's.
00104  *
00105  * Revision 1.18  2001/07/19 21:31:35  msmith
00106  * Fixed operators.
00107  *
00108  * Revision 1.17  2001/07/19 21:27:30  msmith
00109  * Added FPOINT3D operators: + - * / += -= *= /=
00110  *
00111  * Revision 1.15  2001/06/13 16:54:06  mju
00112  * Added FPOINT3D operators
00113  *
00114  * Revision 1.14  2001/03/26 21:31:28  msmith
00115  * Add comparison operators for WPOINT3D.
00116  *
00117  * Revision 1.13  2001/03/14 16:17:42  mju
00118  * Add comparison operators for LPOINT2D.
00119  *
00120  * Revision 1.12  2001/01/09 14:57:31  scowan
00121  * Include memory buffer include file.
00122  *
00123  * Revision 1.11  2001/01/09 00:35:04  scowan
00124  * Added swap functions for points.
00125  *
00126  * Revision 1.10  2001/01/08 17:47:38  scowan
00127  * Added 3D point comparison operators.
00128  *
00129  * Revision 1.9  2001/01/05 18:08:01  mju
00130  * Rename ORIENTATION values.
00131  *
00132  * Revision 1.8  2001/01/05 17:37:50  scowan
00133  * Added orient and dimension enums.
00134  *
00135  * Revision 1.7  2000/07/07 21:47:16  sparsons
00136  * Genitor documentation.
00137  *
00138  * Revision 1.6  1999/07/21 21:13:20  dwilliss
00139  * In an assignment operator overload *this = rhs is an efficient
00140  * way to fill the stack but not real useful otherwise
00141  *
00142  * Revision 1.1  1999/05/05  17:29:49  mju
00143  * Initial revision
00144  * \endif
00145 **/
00146 
00147 #ifndef  INC_MI32_POINT_H
00148 #define  INC_MI32_POINT_H
00149 
00150 //!*****************************************************************************
00151 //!      The structures defined here must not change in size as they are stored
00152 //!      in many existing data files, as well as passed to DLLs.  The members
00153 //!      must remain public and their names may not be changed for any reason.
00154 //!*****************************************************************************
00155 
00156 #ifndef  INC_MI32_STDDEFNS_H
00157 #include <mi32/stddefns.h>
00158 #endif
00159 
00160 #ifndef  INC_MI32_MEMBUF_H
00161 #include <mi32/membuf.h>
00162 #endif
00163 
00164 #ifdef ALLOW_NAMESPACES
00165    #include <cmath>
00166 #else
00167    #include <math.h>
00168 #endif
00169 
00170 //-----------------------------------------------------------------------------
00171 // Global enumerations used in dealing with objects that use points
00172 //-----------------------------------------------------------------------------
00173 
00174 
00175 //! Enumeration of dimension types.
00176 enum DIMENSION {
00177    DIMENSION_2D = 0,             //!< 2 dimensional
00178    DIMENSION_3D = 1              //!< 3 dimensional
00179    };
00180 
00181 //! Enumeration of orientation types assuming right-hand Cartesian system where
00182 //! counter-clocksize sweep from +X axis to +Y axis is 90 degrees.
00183 enum ORIENTATION {
00184    ORIENTATION_Unknown =            0, //!< Orientation is unknown or cannot be computed
00185    ORIENTATION_CounterClockwise =   1, //!< Counter-clockwise
00186    ORIENTATION_Clockwise =          2, //!< Clockwise
00187    ORIENTATION_EmptyPolygon =       3  //!< Polygon is empty, area is 0
00188    };
00189 
00190 
00191 #ifndef GENERATING_DOXYGEN_OUTPUT
00192 //! Forward declarations.
00193 struct DPOINT3D;
00194 #endif //!< GENERATING_DOXYGEN_OUTPUT
00195 
00196 //-----------------------------------------------------------------------------
00197 //!      Define simple structures for use in unions
00198 //!      These structures must not have constructors/destructors
00199 //-----------------------------------------------------------------------------
00200 
00201 struct DPOINT2D_OLD {
00202 
00203    double x;
00204    double y;
00205 
00206    //! Assignment.
00207    inline DPOINT2D_OLD& operator= (
00208       const DPOINT2D& rhs
00209       );
00210 
00211    CHECKSIZE(16);
00212    };
00213 
00214 struct DPOINT3D_OLD {
00215 
00216    double x;
00217    double y;
00218    double z;
00219 
00220    //! Assignment.
00221    inline DPOINT3D_OLD& operator= (
00222       const DPOINT3D& rhs
00223       );
00224 
00225    CHECKSIZE(24);
00226    };
00227 
00228 
00229 //-------------------------------------------------------------------------------------------------------------------
00230 
00231 //! 2D point using 16-bit integer coordinates.
00232 struct WPOINT2D {
00233 
00234    INT16 x;
00235    INT16 y;
00236 
00237    //! Default constructor, performs no initialization.
00238    WPOINT2D (                          
00239       ) {
00240       }
00241 
00242    //! Initialization constructor.
00243    WPOINT2D (                          
00244       INT16 dx,
00245       INT16 dy
00246       ) : x(dx), y(dy) {
00247       }
00248 
00249    CHECKSIZE(4);                       
00250    };
00251 
00252 
00253 //-------------------------------------------------------------------------------------------------------------------
00254 
00255 //! 3D point using 16-bit integer coordinates.
00256 struct WPOINT3D : public WPOINT2D {
00257 
00258    INT16 z;
00259 
00260    //! Default constructor, performs no initialization.
00261    WPOINT3D (                          
00262       ) {
00263       }
00264 
00265    //! Initialize from separate X, Y, Z values.
00266    WPOINT3D (                          
00267       const INT16 dx,
00268       const INT16 dy,
00269       const INT16 dz
00270       ) : WPOINT2D(dx,dy), z(dz) {
00271       }
00272 
00273    //! Initialize from WPOINT2D.
00274    WPOINT3D (                          
00275       const WPOINT2D& rhs
00276       ) : WPOINT2D(rhs), z(0) {
00277       }
00278 
00279    //! Make compiler validate structure size.
00280    CHECKSIZE(6);                       
00281    };
00282 
00283 //! Equal to: Exact match, no fuzzy test enabled.
00284 inline bool operator== (               
00285    const WPOINT3D& lhs, 
00286    const WPOINT3D& rhs
00287    ) {
00288    return (lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z);
00289    }
00290 
00291 //! Not equal to: Exact match, no fuzzy test enabled.
00292 inline bool operator!= (               
00293    const WPOINT3D& lhs, 
00294    const WPOINT3D& rhs
00295    ) {
00296    return (lhs.x != rhs.x || lhs.y != rhs.y || lhs.z != rhs.z);
00297    }
00298 
00299 
00300 //-------------------------------------------------------------------------------------------------------------------
00301 
00302 //! 2D point using 32-bit integer coordinates.
00303 struct LPOINT2D {
00304 
00305    INT32 x;
00306    INT32 y;
00307 
00308    //! Default constructor, performs no initialization.
00309    LPOINT2D (                          
00310       ) {
00311       }
00312 
00313    //! Initialization constructor.
00314    LPOINT2D (                          
00315       INT32 dx,
00316       INT32 dy
00317       ) : x(dx), y(dy) {
00318       }
00319 
00320    //! Construction from WPOINT2D.
00321    LPOINT2D (                          
00322       const WPOINT2D& pt
00323       ) : x(pt.x), y(pt.y) { }
00324 
00325    //! Explicit conversion from DPOINT2D to LPOINT2D, no rounding.
00326    explicit inline LPOINT2D (          
00327       const DPOINT2D& pt
00328       );
00329 
00330    //! Assignment from WPOINT2D.
00331    LPOINT2D& operator= (               
00332       const WPOINT2D& rhs
00333       ) { x = rhs.x; y = rhs.y; return (*this); }
00334 
00335    //! Assignment from DPOINT2D without rounding.
00336    inline LPOINT2D& operator= (        
00337       const DPOINT2D& pt
00338       );
00339 
00340    //! Perform byte-swapping.
00341    void SwapBytes (
00342       ) { ::SwapBytes(x); ::SwapBytes(y); }
00343 
00344    //! Make compiler validate structure size.
00345    CHECKSIZE(8);                       
00346    };
00347 
00348 //! Equality.
00349 inline bool operator== (               
00350    const LPOINT2D& lhs, 
00351    const LPOINT2D& rhs
00352    ) {
00353    return (lhs.x == rhs.x && lhs.y == rhs.y);
00354    }
00355 
00356 //! Inequality.
00357 inline bool operator!= (               
00358    const LPOINT2D& lhs, 
00359    const LPOINT2D& rhs
00360    ) {
00361    return (lhs.x != rhs.x || lhs.y != rhs.y);
00362    }
00363 
00364 //! Perform byte-swapping.
00365 inline void SwapBytes (
00366    LPOINT2D& pt
00367    ) {
00368    pt.SwapBytes();
00369    }
00370 
00371 
00372 //-------------------------------------------------------------------------------------------------------------------
00373 
00374 //! 3D point using 32-bit integer coordinates.
00375 struct LPOINT3D : public LPOINT2D {
00376    
00377    INT32 z;
00378 
00379    //! Default constructor, performs no initialization.
00380    LPOINT3D (                          
00381       ) { }
00382 
00383    //! Initialize from separate X, Y, Z values.
00384    LPOINT3D (                          
00385       const INT32 dx,
00386       const INT32 dy,
00387       const INT32 dz
00388       ) : LPOINT2D(dx,dy), z(dz) { }
00389 
00390    //! Initialize from LPOINT2D.
00391    LPOINT3D (                          
00392       const LPOINT2D& rhs
00393       ) : LPOINT2D(rhs), z(0) { }
00394 
00395    //! Perform byte-swapping.
00396    void SwapBytes (
00397       ) { ::SwapBytes(x); ::SwapBytes(y); ::SwapBytes(z); }
00398 
00399    //! Make compiler validate structure size.
00400    CHECKSIZE(12);                      
00401    };
00402 
00403 //! Perform byte-swapping.
00404 inline void SwapBytes (
00405    LPOINT3D& pt
00406    ) {
00407    pt.SwapBytes();
00408    }
00409 
00410 
00411 //-------------------------------------------------------------------------------------------------------------------
00412 
00413 //! 2D point using 32-bit 'float' coordinates.
00414 struct FPOINT2D {
00415 
00416    float x;
00417    float y;
00418 
00419    //! Default constructor, performs no initialization.
00420    FPOINT2D (                          
00421       ) { }
00422 
00423    //! Initialization constructor.
00424    FPOINT2D (                         
00425       float dx,
00426       float dy
00427       ) : x(dx), y(dy) { }
00428 
00429    //! Construction from WPOINT2D.
00430    FPOINT2D (                          
00431       const WPOINT2D& pt
00432       ) : x(pt.x), y(pt.y) { }
00433 
00434    //! Assignment from WPOINT2D.
00435    FPOINT2D& operator= (               
00436       const WPOINT2D& rhs
00437       ) { x = rhs.x; y = rhs.y; return (*this); }
00438 
00439    //! Assignment from DPOINT2D
00440    FPOINT2D& operator= (               
00441       const DPOINT2D& rhs
00442       );
00443 
00444    //! Negation operator
00445    FPOINT2D operator- (
00446       ) const { return (FPOINT2D(-x,-y)); }
00447 
00448    //! Addition operator
00449    FPOINT2D operator+ (
00450       const FPOINT2D& rhs
00451       ) const { return (FPOINT2D(x+rhs.x,y+rhs.y)); }
00452 
00453    //! Subtraction operator
00454    FPOINT2D operator- (
00455       const FPOINT2D& rhs
00456       ) const { return (FPOINT2D(x-rhs.x,y-rhs.y)); }
00457 
00458    //! Multiplication operator
00459    FPOINT2D operator* (
00460       const float rhs
00461       ) const { return (FPOINT2D(x*rhs,y*rhs)); }
00462 
00463    //! Division operator
00464    FPOINT2D operator/ (
00465       const float rhs
00466       ) const { return (FPOINT2D(x/rhs,y/rhs)); }
00467 
00468    //! Plus equals operator
00469    FPOINT2D operator+= (
00470       const FPOINT2D& rhs
00471       ) { x += rhs.x; y += rhs.y; return (*this); }
00472 
00473    //! Minus equals operator
00474    FPOINT2D operator-= (
00475       const FPOINT2D& rhs
00476       ) { x -= rhs.x; y -= rhs.y; return (*this); }
00477 
00478    //! Times equals operator
00479    FPOINT2D operator*= (
00480       const float rhs
00481       ) { x *= rhs; y *= rhs; return (*this); }
00482 
00483    //! Divided by equals operator
00484    FPOINT2D operator/= (
00485       const float rhs
00486       ) { x /= rhs; y /= rhs; return (*this); }
00487 
00488    //! Return distance between two points.
00489    float GetDistance (                 
00490       const FPOINT2D& pt
00491       ) const {
00492       float dx(pt.x - x);
00493       float dy(pt.y - y);
00494       return (static_cast<float>(sqrt(dx*dx + dy*dy)));
00495       }
00496 
00497    //! Return distance between origin and point.
00498    float GetDistance (                 
00499       ) const {
00500       return (static_cast<float>(sqrt(x*x + y*y)));
00501       }
00502 
00503    //! Return squared distance between two points.
00504    float GetDistanceSquared (       
00505       const FPOINT2D& pt
00506       ) const {
00507       float dx(pt.x - x);
00508       float dy(pt.y - y);
00509       return (static_cast<float>(dx*dx + dy*dy));
00510       }
00511 
00512    //! Return squared distance between origin and point.
00513    float GetDistanceSquared (       
00514       ) const {
00515       return (static_cast<float>(x*x + y*y));
00516       }
00517 
00518    //! Normalize
00519    bool Normalize (        
00520       ) {
00521       const float d = GetDistance();
00522       if (d == 0.0f) return false;
00523       *this /= d;
00524       return true;
00525       }
00526 
00527    //! Normalize
00528    static bool Normalize (       
00529       FPOINT2D& pt
00530       ) {
00531       const float d = pt.GetDistance();
00532       if (d == 0.0f) return false;
00533       pt /= d;
00534       return true;
00535       }
00536 
00537    //! Dot product
00538    float DotProduct (         
00539       const FPOINT2D& pt
00540       ) const { return (x*pt.x + y*pt.y); }
00541 
00542    //! Cross product
00543    float CrossProduct (       
00544       const FPOINT2D& pt
00545       ) const { return (x*pt.y - y*pt.x); }
00546 
00547    //! Perform byte-swapping.
00548    void SwapBytes (
00549       ) { ::SwapBytes(x); ::SwapBytes(y); }
00550 
00551    //! Make compiler validate structure size.
00552    CHECKSIZE(8);                       
00553    };
00554 
00555 //! Exact equality.
00556 inline bool operator== (               
00557    const FPOINT2D& lhs, 
00558    const FPOINT2D& rhs
00559    ) {
00560    return (lhs.x == rhs.x && lhs.y == rhs.y);
00561    }
00562 
00563 //! Exact inequality.
00564 inline bool operator!= (               
00565    const FPOINT2D& lhs, 
00566    const FPOINT2D& rhs
00567    ) {
00568    return (lhs.x != rhs.x || lhs.y != rhs.y);
00569    }
00570 
00571 //! Perform byte-swapping.
00572 inline void SwapBytes (
00573    FPOINT2D& pt
00574    ) {
00575    pt.SwapBytes();
00576    }
00577 
00578 
00579 //-------------------------------------------------------------------------------------------------------------------
00580 
00581 //! 3D point using 32-bit 'float' coordinates.
00582 struct FPOINT3D : public FPOINT2D {
00583 
00584    float z;
00585 
00586    //! Default constructor, performs no initialization.
00587    FPOINT3D (                          
00588       ) {
00589       }
00590 
00591    //! Copy constructor
00592    FPOINT3D (
00593       const FPOINT3D& rhs
00594       ) : FPOINT2D(rhs.x, rhs.y), z(rhs.z) { }
00595 
00596    //! Initialize from separate X, Y, Z values.
00597    FPOINT3D (                          
00598       const float dx,
00599       const float dy,
00600       const float dz
00601       ) : FPOINT2D(dx,dy), z(dz) {
00602       }
00603 
00604    //! Initialize from FPOINT2D.
00605    FPOINT3D (                          
00606       const FPOINT2D& rhs
00607       ) : FPOINT2D(rhs), z(0.0F) {
00608       }
00609 
00610    //! Assignment from DPOINT3D
00611    FPOINT3D& operator= (               
00612       const DPOINT3D& rhs
00613       );
00614 
00615    //! Negation operator
00616    FPOINT3D operator- (
00617       ) const { return (FPOINT3D(-x,-y,-z)); }
00618 
00619    //! Addition operator
00620    FPOINT3D operator+ (
00621       const FPOINT3D& rhs
00622       ) const { return (FPOINT3D(x+rhs.x,y+rhs.y,z+rhs.z)); }
00623 
00624    //! Subtraction operator
00625    FPOINT3D operator- (
00626       const FPOINT3D& rhs
00627       ) const { return (FPOINT3D(x-rhs.x,y-rhs.y,z-rhs.z)); }
00628 
00629    //! Multiplication operator
00630    FPOINT3D operator* (
00631       const float rhs
00632       ) const { return (FPOINT3D(x*rhs,y*rhs,z*rhs)); }
00633 
00634    //! Division operator
00635    FPOINT3D operator/ (
00636       const float rhs
00637       ) const { return (FPOINT3D(x/rhs,y/rhs,z/rhs)); }
00638 
00639    //! Plus equals operator
00640    FPOINT3D operator+= (
00641       const FPOINT3D& rhs
00642       ) { x += rhs.x; y += rhs.y; z += rhs.z; return (*this); }
00643 
00644    //! Minus equals operator
00645    FPOINT3D operator-= (
00646       const FPOINT3D& rhs
00647       ) { x -= rhs.x; y -= rhs.y; z -= rhs.z; return (*this); }
00648 
00649    //! Times equals operator
00650    FPOINT3D operator*= (
00651       const float rhs
00652       ) { x *= rhs; y *= rhs; z *= rhs; return (*this); }
00653 
00654    //! Divided by equals operator
00655    FPOINT3D operator/= (
00656       const float rhs
00657       ) { x /= rhs; y /= rhs; z /= rhs; return (*this); }
00658 
00659    //! Return distance between two points.
00660    float GetDistance (                 
00661       const FPOINT3D& pt
00662       ) const {
00663       float dx(pt.x - x);
00664       float dy(pt.y - y);
00665       float dz(pt.z - z);
00666       return (static_cast<float>(sqrt(dx*dx + dy*dy + dz*dz)));
00667       }
00668 
00669    //! Return distance between origin and point.
00670    float GetDistance (                 
00671       ) const {
00672       return (static_cast<float>(sqrt(x*x + y*y + z*z)));
00673       }
00674 
00675    //! Return squared distance between two points.
00676    float GetDistanceSquared (       
00677       const FPOINT3D& pt
00678       ) const {
00679       float dx(pt.x - x);
00680       float dy(pt.y - y);
00681       float dz(pt.z - z);
00682       return (static_cast<float>(dx*dx + dy*dy + dz*dz));
00683       }
00684 
00685    //! Return squared distance between origin and point.
00686    float GetDistanceSquared (       
00687       ) const {
00688       return (static_cast<float>(x*x + y*y + z*z));
00689       }
00690 
00691    //! Normalize
00692    bool Normalize (        
00693       ) {
00694       const float d = GetDistance();
00695       if (d == 0.0f) return false;
00696       *this /= d;
00697       return true;
00698       }
00699 
00700    //! Normalize
00701    static bool Normalize (       
00702       FPOINT3D& pt
00703       ) {
00704       const float d = pt.GetDistance();
00705       if (d == 0.0f) return false;
00706       pt /= d;
00707       return true;
00708       }
00709 
00710    //! Dot product
00711    float DotProduct (         
00712       const FPOINT3D& pt
00713       ) const { return (x*pt.x + y*pt.y + z*pt.z); }
00714 
00715    //! Cross product
00716    FPOINT3D CrossProduct (       
00717       const FPOINT3D& pt
00718       ) const { return (FPOINT3D(y*pt.z - z*pt.y, z*pt.x - x*pt.z, x*pt.y - y*pt.x)); }
00719 
00720    //! Perform byte-swapping.
00721    void SwapBytes (
00722       ) { ::SwapBytes(x); ::SwapBytes(y); ::SwapBytes(z); }
00723 
00724    //! Make compiler validate structure size.
00725    CHECKSIZE(12);                      
00726    };
00727 
00728 //! Equal to: Exact match, no fuzzy test enabled.
00729 inline bool operator== (               
00730    const FPOINT3D& lhs, 
00731    const FPOINT3D& rhs
00732    ) {
00733    return (lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z);
00734    }
00735 
00736 //! Not equal to: Exact match, no fuzzy test enabled.
00737 inline bool operator!= (               
00738    const FPOINT3D& lhs, 
00739    const FPOINT3D& rhs
00740    ) {
00741    return (lhs.x != rhs.x || lhs.y != rhs.y || lhs.z != rhs.z);
00742    }
00743 
00744 //! Perform byte swapping.
00745 inline void SwapBytes (
00746    FPOINT3D& pt
00747    ) {
00748    pt.SwapBytes();
00749    }
00750 
00751 
00752 //-------------------------------------------------------------------------------------------------------------------
00753 
00754 //! 2D point using 64-bit 'double' coordinates.
00755 struct DPOINT2D {
00756 
00757    double x;
00758    double y;
00759 
00760    //! Default constructor.
00761    DPOINT2D (                          
00762       ) { }
00763 
00764    //! Initialization from separate x and y values.
00765    DPOINT2D (                          
00766       const double dx,
00767       const double dy
00768       ) : x(dx), y(dy) { }
00769 
00770    //! Construction from WPOINT2D.
00771    DPOINT2D (                          
00772       const WPOINT2D& pt
00773       ) : x(pt.x), y(pt.y) { }
00774 
00775    //! Construction from LPOINT2D.
00776    DPOINT2D (                          
00777       const LPOINT2D& pt
00778       ) : x(pt.x), y(pt.y) { }
00779 
00780    //! Construction from FPOINT2D.
00781    DPOINT2D (                          
00782       const FPOINT2D& pt
00783       ) : x(pt.x), y(pt.y) { }
00784 
00785    //! Construction from DPOINT2D_OLD.
00786    DPOINT2D (
00787       const DPOINT2D_OLD& pt
00788       ) : x(pt.x), y(pt.y) { }
00789 
00790    //! Assignment from WPOINT2D.
00791    DPOINT2D& operator= (               
00792       const WPOINT2D& rhs
00793       ) { x = rhs.x; y = rhs.y; return (*this); }
00794 
00795    //! Assignment from LPOINT2D.
00796    DPOINT2D& operator= (               
00797       const LPOINT2D& rhs
00798       ) { x = rhs.x; y = rhs.y; return (*this); }
00799 
00800    //! Assignment from FPOINT2D.
00801    DPOINT2D& operator= (               
00802       const FPOINT2D& rhs
00803       ) { x = rhs.x; y = rhs.y; return (*this); }
00804 
00805    //! Assignment from DPOINT2D_OLD.
00806    DPOINT2D& operator= (               
00807       const DPOINT2D_OLD& rhs
00808       ) { x = rhs.x; y = rhs.y; return (*this); }
00809       
00810    //! Negation operator
00811    DPOINT2D operator- (
00812       ) { return (DPOINT2D(-x,-y)); }
00813 
00814    //! Addition operator
00815    DPOINT2D operator+ (
00816       const DPOINT2D& rhs
00817       ) const { return (DPOINT2D(x+rhs.x,y+rhs.y)); }
00818 
00819    //! Subtraction operator
00820    DPOINT2D operator- (
00821       const DPOINT2D& rhs
00822       ) const { return (DPOINT2D(x-rhs.x,y-rhs.y)); }
00823 
00824    //! Multiplication operator
00825    DPOINT2D operator* (
00826       const double rhs
00827       ) const { return (DPOINT2D(x*rhs,y*rhs)); }
00828 
00829    //! Division operator
00830    DPOINT2D operator/ (
00831       const double rhs
00832       ) const { return (DPOINT2D(x/rhs,y/rhs)); }
00833 
00834    //! Plus equals operator
00835    DPOINT2D operator+= (
00836       const DPOINT2D& rhs
00837       ) { x += rhs.x; y += rhs.y; return (*this); }
00838 
00839    //! Minus equals operator
00840    DPOINT2D operator-= (
00841       const DPOINT2D& rhs
00842       ) { x -= rhs.x; y -= rhs.y; return (*this); }
00843 
00844    //! Times equals operator
00845    DPOINT2D operator*= (
00846       const double rhs
00847       ) { x *= rhs; y *= rhs; return (*this); }
00848 
00849    //! Divided by equals operator
00850    DPOINT2D operator/= (
00851       const double rhs
00852       ) { x /= rhs; y /= rhs; return (*this); }
00853 
00854    //! Return angle of the segment, 'this' is the basepoint
00855    double GetAngle (
00856       const DPOINT2D& pt
00857       ) const {
00858       double dx(pt.x - x);
00859       double dy(pt.y - y);
00860       if (dx == 0.0 && dy == 0.0) return (0.0);
00861       return (atan2(dy, dx));
00862       }
00863 
00864    //! Return angle of the segment from origin to point
00865    double GetAngle (
00866       ) const {
00867       if (x == 0.0 && y == 0.0) return (0.0);
00868       return (atan2(y, x));
00869       }
00870 
00871    //! Return distance between two points.
00872    double GetDistance (                
00873       const DPOINT2D& pt
00874       ) const {
00875       double dx(pt.x - x);
00876       double dy(pt.y - y);
00877       return (sqrt(dx*dx + dy*dy));
00878       }
00879 
00880    //! Return distance between origin and point.
00881    double GetDistance (
00882       ) const {
00883       return (sqrt(x*x + y*y));
00884       }
00885 
00886    //! Return squared distance between two points.
00887    double GetDistanceSquared (         
00888       const DPOINT2D& pt
00889       ) const {
00890       double dx(pt.x - x);
00891       double dy(pt.y - y);
00892       return (dx*dx + dy*dy);
00893       }
00894 
00895    //! Get ordinate at specified index.
00896    //! Allows access like array of appropriate dimension (2 or 3).
00897    double GetOrdinate (
00898       int index                     //!< Index (0-1) or (0-2) if 3D.
00899       ) const { return (reinterpret_cast<const double*>(this)[index]); }
00900 
00901    //! Convert the a DPOINT2D into an LPOINT2D.
00902    LPOINT2D RoundToLong (              
00903       ) const {
00904       return (LPOINT2D(FAST_ROUND(x), FAST_ROUND(y)));
00905       }
00906 
00907    //! Set ordinate at specified index.
00908    //! Allows access like array of appropriate dimension (2 or 3).
00909    void SetOrdinate (
00910       int index,                    //!< Index (0-1) or (0-2) if 3D.
00911       double value
00912       ) { reinterpret_cast<double*>(this)[index] = value; }
00913 
00914    //! Shift point using another point.
00915    void Shift (                        
00916       const DPOINT2D& value
00917       ) {
00918       x += value.x;
00919       y += value.y;
00920       return;
00921       }
00922 
00923    //! Shift point by a single value.
00924    void Shift (                        
00925       const double xval,
00926       const double yval
00927       ) {
00928       x += xval;
00929       y += yval;
00930       return;
00931       }
00932 
00933    //! Perform byte-swapping.
00934    void SwapBytes (
00935       ) { ::SwapBytes(x); ::SwapBytes(y); }
00936 
00937    //! Convert the a DPOINT2D into an LPOINT2D.
00938    LPOINT2D TruncateToLong (              
00939       ) const {
00940       return (LPOINT2D(FAST_TRUNCATE(x), FAST_TRUNCATE(y)));
00941       }
00942 
00943    //! Make compiler validate structure size.
00944    CHECKSIZE(16);                      
00945    };
00946 
00947 
00948 //! Equal to: Exact match, no fuzzy test enabled.
00949 inline bool operator== (               
00950    const DPOINT2D& lhs, 
00951    const DPOINT2D& rhs
00952    ) {
00953    return (lhs.x == rhs.x && lhs.y == rhs.y);
00954    }
00955 
00956 //! Not equal to: Exact match, no fuzzy test enabled.
00957 inline bool operator!= (               
00958    const DPOINT2D& lhs, 
00959    const DPOINT2D& rhs
00960    ) {
00961    return (lhs.x != rhs.x || lhs.y != rhs.y);
00962    }
00963 
00964 //! Less than: Exact match, no fuzzy test enabled.
00965 inline bool operator< (                
00966    const DPOINT2D& lhs,
00967    const DPOINT2D& rhs
00968    ) {
00969    return (lhs.x < rhs.x || (lhs.x == rhs.x && lhs.y < rhs.y));
00970    }
00971 
00972 //! Greater than: Exact match, no fuzzy test enabled.
00973 inline bool operator> (                
00974    const DPOINT2D& lhs, 
00975    const DPOINT2D& rhs
00976    ) {
00977    return (lhs.x > rhs.x || (lhs.x == rhs.x && lhs.y > rhs.y));
00978    }
00979 
00980 //! Less than or equal to: Exact match, no fuzzy test enabled.
00981 inline bool operator<= (               
00982    const DPOINT2D& lhs, 
00983    const DPOINT2D& rhs
00984    ) {
00985    return (lhs == rhs || lhs < rhs);
00986    }
00987 
00988 //! Greater than or equal to: Exact match, no fuzzy test enabled.
00989 inline bool operator>= (              
00990    const DPOINT2D& lhs, 
00991    const DPOINT2D& rhs
00992    ) {
00993    return (lhs == rhs || lhs > rhs);
00994    }
00995 
00996 //! Perform byte-swapping.
00997 inline void SwapBytes (
00998    DPOINT2D& pt
00999    ) {
01000    pt.SwapBytes();
01001    }
01002 
01003 
01004 //-------------------------------------------------------------------------------------------------------------------
01005 
01006 //! 3D point using 64-bit 'double' coordinates.
01007 struct DPOINT3D : public DPOINT2D {
01008 
01009    double z;
01010 
01011    //! Default constructor, performs no initialization.
01012    DPOINT3D (                          
01013       ) {
01014       }
01015 
01016    //! Copy constructor
01017    DPOINT3D (
01018       const DPOINT3D& rhs
01019       ) : DPOINT2D(rhs.x, rhs.y), z(rhs.z) { }
01020 
01021    //! Initialize from separate X, Y, Z values.
01022    DPOINT3D (                          
01023       const double dx,
01024       const double dy,
01025       const double dz
01026       ) : DPOINT2D(dx, dy), z(dz) { }
01027 
01028    //! Initialize from DPOINT2D.
01029    DPOINT3D (                          
01030       const DPOINT2D& rhs
01031       ) : DPOINT2D(rhs), z(0.0) { }
01032 
01033    //! Implicit conversion from DPOINT3D_OLD.
01034    DPOINT3D (                          
01035       const DPOINT3D_OLD& rhs
01036       ) : DPOINT2D(rhs.x,rhs.y), z(rhs.z) { }
01037 
01038    //! Assignment from DPOINT2D.
01039    DPOINT3D& operator= (               
01040       const DPOINT2D& rhs
01041       ) { x = rhs.x; y = rhs.y; z = 0.0; return (*this); }
01042 
01043    //! Assignment from FPOINT3D.
01044    DPOINT3D& operator= (               
01045       const FPOINT3D& rhs
01046       ) { x = rhs.x; y = rhs.y; z = rhs.z; return (*this); }
01047 
01048    //! Assignment from DPOINT3D_OLD.
01049    DPOINT3D& operator= (               
01050       const DPOINT3D_OLD& rhs
01051       ) { x = rhs.x; y = rhs.y; z = rhs.z; return (*this); }
01052 
01053    //! Negation operator
01054    DPOINT3D operator- (
01055       ) const { return (DPOINT3D(-x,-y,-z)); }
01056 
01057    //! Addition operator
01058    DPOINT3D operator+ (
01059       const DPOINT3D& rhs
01060       ) const { return (DPOINT3D(x+rhs.x,y+rhs.y,z+rhs.z)); }
01061 
01062    //! Subtraction operator
01063    DPOINT3D operator- (
01064       const DPOINT3D& rhs
01065       ) const { return (DPOINT3D(x-rhs.x,y-rhs.y,z-rhs.z)); }
01066 
01067    //! Multiplication operator
01068    DPOINT3D operator* (
01069       const double rhs
01070       ) const { return (DPOINT3D(x*rhs,y*rhs,z*rhs)); }
01071 
01072    //! Division operator
01073    DPOINT3D operator/ (
01074       const double rhs
01075       ) const { return (DPOINT3D(x/rhs,y/rhs,z/rhs)); }
01076 
01077    //! Plus equals operator
01078    DPOINT3D operator+= (
01079       const DPOINT3D& rhs
01080       ) { x += rhs.x; y += rhs.y; z += rhs.z; return (*this); }
01081 
01082    //! Minus equals operator
01083    DPOINT3D operator-= (
01084       const DPOINT3D& rhs
01085       ) { x -= rhs.x; y -= rhs.y; z -= rhs.z; return (*this); }
01086 
01087    //! Times equals operator
01088    DPOINT3D operator*= (
01089       const double rhs
01090       ) { x *= rhs; y *= rhs; z *= rhs; return (*this); }
01091 
01092    //! Divided by equals operator
01093    DPOINT3D operator/= (
01094       const double rhs
01095       ) { x /= rhs; y /= rhs; z /= rhs; return (*this); }
01096 
01097    //! Compute the cross product of two DPOINT3Ds
01098    //! @note "this" cannot be either of the two input points
01099    void CrossProduct (
01100       const DPOINT3D& in1,
01101       const DPOINT3D& in2
01102       ) {
01103       x = in1.y * in2.z - in2.y * in1.z;
01104       y = in1.z * in2.x - in2.z * in1.x;
01105       z = in1.x * in2.y - in2.x * in1.y;
01106       }
01107 
01108    //! Compute the dot product of two DPOINT3Ds
01109    static double DotProduct (
01110       const DPOINT3D& in1,
01111       const DPOINT3D& in2
01112       ) {
01113       return (in1.x * in2.x + in1.y * in2.y + in1.z * in2.z);
01114       }
01115 
01116    //! Return distance between origin and point.
01117    double GetDistance (                
01118       ) const {
01119       return (sqrt(x*x + y*y + z*z));
01120       }
01121 
01122    //! Return distance between two points.
01123    double GetDistance (                
01124       const DPOINT3D& pt
01125       ) const {
01126       double dx(pt.x - x);
01127       double dy(pt.y - y);
01128       double dz(pt.z - z);
01129       return (sqrt(dx*dx + dy*dy + dz*dz));
01130       }
01131 
01132    //! Return squared distance between two points.
01133    double GetDistanceSquared (         
01134       const DPOINT3D& pt
01135       ) const {
01136       double dx(pt.x - x);
01137       double dy(pt.y - y);
01138       double dz(pt.z - z);
01139       return (dx*dx + dy*dy + dz*dz);
01140       }
01141 
01142    //! Return squared distance between origin and point.
01143    double GetDistanceSquared (         
01144       ) const {
01145       return (x*x + y*y + z*z);
01146       }
01147 
01148    //! Normalize 3D vector represented by point.
01149    void Normalize (                    
01150       ) {
01151       double d = sqrt(x*x + y*y + z*z);
01152       if (d != 0.0) {
01153          x /= d;
01154          y /= d;
01155          z /= d;
01156          }
01157       return;
01158       }
01159 
01160    //! Shift point using another point.
01161    void Shift (                        
01162       const DPOINT3D& value
01163       ) { DPOINT2D::Shift(value); z += value.z; }
01164 
01165    //! Shift point by a single value.                                         
01166    void Shift (                        
01167       const double xval,
01168       const double yval,
01169       const double zval
01170       ) { DPOINT2D::Shift(xval, yval); z += zval; }
01171 
01172    //! Perform byte-swapping.
01173    void SwapBytes (
01174       ) { ::SwapBytes(x); ::SwapBytes(y); ::SwapBytes(z); }
01175 
01176    //! Make compiler validate structure size.
01177    CHECKSIZE(24);                      
01178    };
01179 
01180 
01181 //-------------------------------------------------------------------------------------------------------------------
01182 
01183 //! 3D homogeneous point using 32-bit 'float' coordinates.
01184 struct FPOINT3DH {
01185 
01186    float x;
01187    float y;
01188    float z;
01189    float w;
01190 
01191    //! Default constructor initialize with (0.0, 0.0, 0.0, 1.0).
01192    FPOINT3DH (
01193       ) : x(0.0f), y(0.0f), z(0.0f), w(1.0f) { }
01194 
01195    //! Initialize from separate X, Y, Z, W values.
01196    FPOINT3DH (                         
01197       const float dx,
01198       const float dy,
01199       const float dz,
01200       const float dw = 1.0f
01201       ) : x(dx), y(dy), z(dz), w(dw) { }
01202 
01203    //! Initialize from FPOINT3D.
01204    FPOINT3DH (                         
01205       const FPOINT3D& p
01206       ) : x(p.x), y(p.y), z(p.z), w(1.0f) { }
01207 
01208    //! Assignment from FPOINT3D
01209    FPOINT3DH& operator= (              
01210       const FPOINT3D& rhs
01211       ) { x = rhs.x; y = rhs.y; z = rhs.z; w = 1.0f; return (*this); }
01212 
01213    //! Assignment from DPOINT3DH
01214    inline FPOINT3DH& operator= (             
01215       const DPOINT3DH& rhs
01216       );
01217 
01218    //! Negation operator
01219    FPOINT3DH operator- (
01220       ) const { return (FPOINT3DH(-x,-y,-z,-w)); }
01221 
01222    //! Addition operator
01223    FPOINT3DH operator+ (
01224       const FPOINT3DH& rhs
01225       ) const { return (FPOINT3DH(x+rhs.x,y+rhs.y,z+rhs.z,w+rhs.w)); }
01226 
01227    //! Subtraction operator
01228    FPOINT3DH operator- (
01229       const FPOINT3DH& rhs
01230       ) const { return (FPOINT3DH(x-rhs.x,y-rhs.y,z-rhs.z,w-rhs.w)); }
01231 
01232    //! Multiplication operator
01233    FPOINT3DH operator* (
01234       const float rhs
01235       ) const { return (FPOINT3DH(x*rhs,y*rhs,z*rhs,w*rhs)); }
01236 
01237    //! Division operator
01238    FPOINT