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