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