Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

points.H

Go to the documentation of this file.
00001 #ifndef POINTS_H_IS_INCLUDED
00002 #define POINTS_H_IS_INCLUDED
00003 
00004 /*!
00005  *  \file points.H
00006  *  \brief Definitions of geometry classes for various coordinate systems.
00007  *  \ingroup group_MLIB
00008  *
00009  *  \remark This file should probably be renamed to something like
00010  *  coordinate_systems.H.
00011  *
00012  */
00013 
00014 namespace mlib {
00015 
00016 /*!
00017  *  \defgroup group_world_coordinate_system "World" Coordinate System
00018  *  \brief 3D coordinates used for "world space" and "object space".
00019  *  \ingroup group_MLIB
00020  *
00021  */
00022 //@{
00023    
00024 class Wpt;
00025 class Wvec;
00026 class Wtransf;  // 4x4 transformation
00027 class Wquat;    // quaternion representing a rotation
00028 class Wplane;
00029 class Wline;
00030 class Wpt_list;
00031 
00032 //@}
00033 
00034 /*!
00035  *  \defgroup group_xy_coordinate_system "XY" Coordinate System
00036  *  \brief 2D screen coordinates running from [-1,-1] to [1,1] within window.
00037  *  \ingroup group_MLIB
00038  *
00039  */
00040 //@{
00041    
00042 class XYpt;
00043 class XYvec;
00044 class XYline;
00045 class XYpt_list;
00046 
00047 //@}
00048 
00049 /*!
00050  *  \defgroup group_ndc_coordinate_system "NDC" Coordinate System
00051  *  \brief Normalized Device Coordinates.  2D screen coordinates running from
00052  *  -1 to 1 in shorter window dimension, and from -A to A in the longer window
00053  *  dimension, where A is the aspect ratio.
00054  *  \ingroup group_MLIB
00055  *
00056  */
00057 //@{
00058    
00059 class NDCpt;
00060 class NDCvec;
00061 class NDCline;
00062 class NDCpt_list;
00063 
00064 //@}
00065 
00066 /*!
00067  *  \defgroup group_ndcz_coordinate_system "NDCZ" Coordinate System
00068  *  \brief Same as \ref group_ndc_coordinate_system "NDC" but with a 3rd
00069  *  coordinate z = depth.
00070  *  \ingroup group_MLIB
00071  *
00072  */
00073 //@{
00074 
00075 class NDCZvec;
00076 class NDCZpt;
00077 class NDCZpt_list;
00078 
00079 //@}
00080 
00081 /*!
00082  *  \defgroup group_pixel_coordinate_system "PIXEL" Coordinate System
00083  *  \brief 2D floating point screen coordinates representing pixel
00084  *  locations.  E.g. the lower left corner of the screen is (0,0),
00085  *  and the upper right is (w,h) (i.e. window width and height).
00086  *  \ingroup group_MLIB
00087  *
00088  */
00089 //@{
00090 
00091 class VEXEL;
00092 class PIXEL;
00093 class PIXELline;
00094 class PIXEL_list;
00095 
00096 //@}
00097 
00098 /*!
00099  *  \defgroup group_uv_coordinate_system "UV" Coordinate System
00100  *  \brief 2D coordinates that can be used for texture mapping, e.g.
00101  *  \ingroup group_MLIB
00102  *
00103  */
00104 //@{
00105 
00106 class UVpt;
00107 class UVvec;
00108 class UVline;
00109 class UVpt_list;
00110 
00111 //@}
00112 
00113 // The evil capital-C thing (shorthand for "const"):
00114 
00115 //! \addtogroup group_world_coordinate_system
00116 //@{
00117 
00118 typedef const class Wvec                CWvec;
00119 typedef const class Wpt                 CWpt;
00120 typedef const class Wpt_list            CWpt_list;
00121 typedef const class Wtransf             CWtransf;
00122 typedef const class Wplane              CWplane;
00123 typedef const class Wline               CWline;
00124 typedef const class Wquat               CWquat;
00125 
00126 //@}
00127 
00128 //! \addtogroup group_xy_coordinate_system
00129 //@{
00130 
00131 // Screen-space coordinates
00132 // (ranges from [-1,1] in X and Y):
00133 typedef const class XYvec               CXYvec;
00134 typedef const class XYpt                CXYpt;
00135 typedef const class XYpt_list           CXYpt_list;
00136 typedef const class XYline              CXYline;
00137 
00138 //@}
00139 
00140 //! \addtogroup group_ndc_coordinate_system
00141 //@{
00142 
00143 // Aspect ratio-preserving screen-space coordinates
00144 // (ranges from [-1,1] in shorter window dimension):
00145 typedef const class NDCvec              CNDCvec;
00146 typedef const class NDCpt               CNDCpt;
00147 typedef const class NDCpt_list          CNDCpt_list;
00148 
00149 //@}
00150 
00151 //! \addtogroup group_ndcz_coordinate_system
00152 //@{
00153 
00154 // Same as NDC coordinates but with a depth coordinate:
00155 typedef const class NDCZvec             CNDCZvec;
00156 typedef const class NDCZvec_list        CNDCZvec_list;
00157 typedef const class NDCZpt              CNDCZpt;
00158 typedef const class NDCZpt_list         CNDCZpt_list;
00159 
00160 //@}
00161 
00162 //! \addtogroup group_pixel_coordinate_system
00163 //@{
00164 
00165 // PIXEL coordinates - 2D floating point coordinates
00166 // with (0,0) = lower left corner, (w, h) = upper right:
00167 typedef const class VEXEL               CVEXEL;
00168 typedef const class PIXEL               CPIXEL;
00169 typedef const class PIXEL_list          CPIXEL_list;
00170 
00171 //@}
00172 
00173 //! \addtogroup group_uv_coordinate_system
00174 //@{
00175 
00176 // UV coordinates (e.g. for texture mapping):
00177 typedef const class UVvec               CUVvec;
00178 typedef const class UVpt                CUVpt;
00179 typedef const class UVpt_list           CUVpt_list;
00180 typedef const class UVline              CUVline;
00181 
00182 //@}
00183 
00184 } // namespace mlib
00185 
00186 #include "mlib/global.H"
00187 #include "mlib/point2.H"
00188 #include "mlib/point3.H"
00189 #include "mlib/plane.H"
00190 #include "mlib/mat4.H"
00191 #include "mlib/quat.H"
00192 #include "mlib/nearest_pt.H"
00193 
00194 namespace mlib {
00195 
00196 //! \addtogroup group_world_coordinate_system
00197 //@{
00198 
00199 /*!
00200  *  \brief A vector in World coordinates.
00201  *
00202  */
00203 class Wvec : public Vec3<Wvec> {
00204    
00205    protected:
00206    
00207       static CWvec _null_vec;
00208       static CWvec _x_axis;
00209       static CWvec _y_axis;
00210       static CWvec _z_axis;
00211 
00212    public:
00213 
00214       //! \name Constructors
00215       //@{
00216          
00217       Wvec() {}
00218       Wvec(CXYpt&);
00219       Wvec(CNDCZvec& , CWtransf& );
00220       Wvec(double x, double y, double z) : Vec3<Wvec>(x,y,z) {}
00221       Wvec(CWpt& , CVEXEL&);
00222       
00223       //@}
00224       
00225       static CWvec& null() { return Wvec::_null_vec; }
00226       static CWvec&    X() { return Wvec::_x_axis; }
00227       static CWvec&    Y() { return Wvec::_y_axis; }
00228       static CWvec&    Z() { return Wvec::_z_axis; }
00229       
00230 };
00231 
00232 #ifdef JOT_NEEDS_DOUBLE_STAR_EXPLICIT
00233 // Should be able to define this once for Vec3, but that
00234 // doesn't work (then again, we have to do this because of
00235 // template problems in the first place)
00236 inline Wvec operator *(double s, const Wvec& p) { return p * s;}
00237 #endif
00238 
00239 /*!
00240  *  \brief A point in World coordinates.
00241  *
00242  */
00243 class Wpt : public Point3<Wpt, Wvec> {
00244    
00245    protected:
00246    
00247       static CWpt _origin;
00248 
00249    public:
00250    
00251       //! \name Constructors
00252       //@{
00253    
00254       Wpt() { }
00255       explicit Wpt(double s) : Point3<Wpt,Wvec>(s) { }
00256       Wpt(double x, double y, double z):Point3<Wpt,Wvec>(x,y,z) { }
00257       Wpt(CXYpt& );
00258       Wpt(CNDCZpt& );
00259       Wpt(CXYpt& , double d);
00260       Wpt(CXYpt& , CWpt& );
00261    
00262       inline Wpt(CWtransf& );
00263       inline Wpt(CWline& , CWline& );
00264       inline Wpt(CWline& , CWpt  & );
00265       inline Wpt(CWplane&, CWline& );
00266       
00267       //@}
00268       
00269       //! \name Misc. Functions
00270       //@{
00271    
00272       bool in_frustum() const;
00273       
00274       //@}
00275    
00276       static CWpt& Origin() { return Wpt::_origin; }
00277       
00278 };
00279 
00280 #ifdef JOT_NEEDS_DOUBLE_STAR_EXPLICIT
00281 inline Wpt operator *(double s, const Wpt& p) { return p * s;}
00282 #endif
00283 
00284 /*!
00285  *  \brief A line in World coordinates.
00286  *
00287  */
00288 class Wline : public Line<Wline, Wpt, Wvec> {
00289    
00290    public:
00291    
00292       //! \name Constructors
00293       //@{
00294    
00295       Wline() { }
00296       Wline(CWpt& p,  CWvec& v) : Line<Wline,Wpt,Wvec>(p,v)  {}
00297       Wline(CWpt& p1, CWpt & p2): Line<Wline,Wpt,Wvec>(p1,p2) {}
00298       Wline(CXYpt&x)            : Line<Wline,Wpt,Wvec>(Wpt(x),Wvec(x)) {}
00299       
00300       //@}
00301    
00302 };
00303 
00304 /*!
00305  *  \brief A tranform (or matrix) in World coordinates.
00306  *
00307  *  4x4 matrix for transforming Wpts and Wvecs
00308  *
00309  */
00310 class Wtransf : public Mat4<Wtransf,Wpt,Wvec,Wline,Wquat> {
00311    
00312    public:
00313    
00314       //! \name Constructors
00315       //@{
00316    
00317       Wtransf()   { }
00318       Wtransf(Vec4 row0, Vec4 row1, Vec4 row2, Vec4 row3, bool perspec = false)
00319          : Mat4<Wtransf,Wpt,Wvec,Wline,Wquat>(row0, row1, row2, row3, perspec) { }
00320       Wtransf(CWpt  &   origin, 
00321               CWvec &     xDir, 
00322               CWvec &     yDir, 
00323               CWvec &     zDir) 
00324               : Mat4<Wtransf,Wpt,Wvec,Wline,Wquat>(origin,xDir,yDir,zDir) { }
00325       Wtransf(CWvec &     col0, 
00326               CWvec &     col1, 
00327               CWvec &     col2) 
00328               : Mat4<Wtransf,Wpt,Wvec,Wline,Wquat>(col0,col1,col2) { }
00329       Wtransf(CWpt  &   origin, 
00330               CWvec &     xDir, 
00331               CWvec &     yDir) 
00332               : Mat4<Wtransf,Wpt,Wvec,Wline,Wquat>(origin,xDir,yDir) { }
00333       Wtransf(CWline&   axis)   : Mat4<Wtransf,Wpt,Wvec,Wline,Wquat>(axis) { }
00334       Wtransf(CWpt  &   origin) : Mat4<Wtransf,Wpt,Wvec,Wline,Wquat>(origin) { }
00335       
00336       //@}
00337       
00338 };
00339 
00340 /*!
00341  *  \brief A plane in World coordinates.
00342  *
00343  */
00344 class Wplane : public Plane<Wplane,Wpt,Wvec,Wline> {
00345    
00346    public:
00347    
00348       //! \name Constructors
00349       //@{
00350    
00351       Wplane()                     { }
00352       Wplane(CWvec & n, double d)             : Plane<Wplane,Wpt,Wvec,Wline>(n,d) { }
00353       Wplane(CWpt&n, CWvec&v)                 : Plane<Wplane,Wpt,Wvec,Wline>(n,v) { }
00354       Wplane(CWpt&n, CWpt&p1, CWpt&p2)        : Plane<Wplane,Wpt,Wvec,Wline>(n,p1,p2) { }
00355       Wplane(CWpt&p, CWvec&v1, CWvec&v2)      : Plane<Wplane,Wpt,Wvec,Wline>(p,v1,v2) { }
00356       Wplane(CWpt plg[], int n)               : Plane<Wplane,Wpt,Wvec,Wline>(plg,n) { }
00357       Wplane(CWpt plg[], int n, CWvec& normal): Plane<Wplane,Wpt,Wvec,Wline>(plg,n,normal) { }
00358       
00359       //@}
00360    
00361 };
00362 
00363 inline Wpt::Wpt(CWtransf& t)           { (*this) = t.origin(); }
00364 inline Wpt::Wpt(CWline & a, CWline& b) { (*this) = a.intersect(b); }
00365 inline Wpt::Wpt(CWline & a, CWpt  & b) { (*this) = a.project(b); }
00366 inline Wpt::Wpt(CWplane& a, CWline& b) { (*this) = a.intersect(b); }
00367 
00368 /*!
00369  *  \brief A list of points in World coordinates.
00370  *
00371  */
00372 class Wpt_list : public Point3list<Wpt_list,Wtransf,Wpt,Wvec,Wline> {
00373    
00374    public:
00375    
00376       //! \name Constructors
00377       //@{
00378    
00379       Wpt_list(int max=0)
00380          : Point3list<Wpt_list,Wtransf,Wpt,Wvec,Wline>(max) {}
00381       
00382       Wpt_list(const Point3list<Wpt_list,Wtransf,Wpt,Wvec,Wline>& p)
00383          : Point3list<Wpt_list,Wtransf,Wpt,Wvec,Wline>(p)
00384       {
00385          // XXX - base class Point3list updates length, but
00386          //       the compiler (linux anyway) ignores it.
00387          //       So now we have to do it again (?):
00388          update_length();
00389       }
00390       
00391       Wpt_list(const Point3list<Wpt_list,Wtransf,Wpt,Wvec,Wline>& p, CWtransf& t)
00392          : Point3list<Wpt_list,Wtransf,Wpt,Wvec,Wline>(p,t)
00393       {
00394          // XXX - stupid compiler?
00395          update_length();
00396       }
00397       
00398       //@}
00399       
00400       //! \name Projection Functions
00401       //@{
00402    
00403       //! \brief Project to screen coords, provided all Wpts lie in
00404       //! the view frustum.
00405       bool project(XYpt_list&  ret) const;
00406       //! \brief Project to screen coords, provided all Wpts lie in
00407       //! the view frustum.
00408       bool project(PIXEL_list& ret) const;
00409       
00410       //@}
00411       
00412       //! \name Nearest Point Functions
00413       //@{
00414    
00415       //! \brief Returns index of the *vertex* of the polyline
00416       //! that is closest to the given screen-space point
00417       //! (distance measured in PIXELs). Skips vertices
00418       //! that lie outside the view frustum. Returns -1 if
00419       //! no vertices lie in the frustum.
00420       int closest_vertex(CPIXEL& p) const;
00421       
00422       //@}
00423       
00424       //! \name Best-Fit Plane Functions
00425       //@{
00426    
00427       //! \brief Return the best-fit plane.
00428       bool get_best_fit_plane(Wplane& P) const;
00429       
00430       //! \brief Return the best-fit plane if the fit is good.  Parameter
00431       //! 'len_scale' is multiplied by the length of the polyline
00432       //! to yield a threshold. The fit is considered good if
00433       //! every point lies within the threshold distance from the
00434       //! plane.
00435       bool get_plane(Wplane& P, double len_scale=1e-3) const;
00436    
00437       //! \brief Return true if get_plane succeeds with the given threshold.
00438       bool is_planar(double len_scale=1e-3) const {
00439          Wplane P;
00440          get_plane(P, len_scale);
00441          return P.is_valid();
00442       }
00443    
00444       //! \brief Convenience: compute the best-fit plane and return its normal.
00445       bool get_plane_normal(Wvec& n) {
00446          Wplane P;
00447          if (!get_plane(P))
00448             return false;
00449          n = P.normal();
00450          return true;   
00451       }
00452       
00453       //@}
00454       
00455 };
00456 
00457 //! \name Overloaded Arithmetic Operators
00458 //@{
00459 
00460 //! \brief Multiplies a transformation matrix by every point in the list.
00461 //! \relates Wpt_list
00462 inline Wpt_list 
00463 operator *(CWtransf& x, CWpt_list& pts) {
00464    Wpt_list ret;
00465    for (int i=0; i<pts.num(); i++)
00466       ret += (x * pts[i]);
00467    return ret;
00468 }
00469 
00470 //! \brief Multiplies all the points in the list by a scalar constant.
00471 //! \relates Wpt_list
00472 inline Wpt_list
00473 operator *(CWpt_list& pts, double t) {
00474    Wpt_list ret;
00475    for (int i = 0; i < pts.num(); i++)
00476       ret += (pts[i]*t);
00477    return ret;
00478 }
00479 
00480 //! \brief Adds all the points in one list to the corresponding points in another
00481 //! list.  The two lists must contain the same number of points.
00482 //! \relates Wpt_list
00483 inline Wpt_list
00484 operator +(CWpt_list& pts1, CWpt_list& pts2) {
00485    assert(pts1.num() == pts2.num());
00486    Wpt_list ret;
00487    for (int i=0; i<pts1.num(); i++)
00488       ret += (pts1[i] + pts2[i]);
00489    return ret;
00490 }
00491 
00492 //@}
00493 
00494 /*!
00495  *  \brief A quaternion in World coordinates.
00496  *
00497  */
00498 class Wquat : public Quat<Wquat, Wtransf, Wpt, Wvec, Wline>
00499 {
00500    
00501    public:
00502    
00503       //! \name Constructors
00504       //@{
00505    
00506       Wquat() {}
00507       Wquat(CWvec& v, double w)
00508          : Quat<Wquat, Wtransf, Wpt, Wvec, Wline>(v,w) {}
00509       Wquat(double s)
00510          : Quat<Wquat, Wtransf, Wpt, Wvec, Wline>(Wvec(),s) {}
00511       Wquat(CWtransf& t)
00512          : Quat<Wquat, Wtransf, Wpt, Wvec, Wline>(t) {}
00513       Wquat(CWvec& v1, CWvec& v2)
00514          : Quat<Wquat, Wtransf, Wpt, Wvec, Wline>(v1,v2) {}
00515       
00516       //@}
00517 
00518 };
00519 
00520 //@}
00521 
00522 } // namespace mlib
00523 
00524 namespace mlib {
00525 
00526 //! \addtogroup group_xy_coordinate_system
00527 //! XY coordinates : -1 to 1 normalized coordinates
00528 //@{
00529 
00530 /*!
00531  *  \brief A vector in XY coordinates.
00532  *
00533  */
00534 class XYvec : public Vec2<XYvec> {
00535 
00536    protected:
00537    
00538       static CXYvec _null_vec;
00539       static CXYvec _x_axis;
00540       static CXYvec _y_axis;
00541 
00542    public:
00543    
00544       //! \name Constructors
00545       //@{
00546          
00547       XYvec() { }
00548       XYvec(double x, double y):Vec2<XYvec>(x,y) { }
00549       XYvec(CNDCvec& );
00550       XYvec(CVEXEL& );
00551       
00552       //@}
00553       
00554       static CXYvec& null() { return XYvec::_null_vec; }
00555       static CXYvec&    X() { return XYvec::_x_axis; }
00556       static CXYvec&    Y() { return XYvec::_y_axis; }
00557 
00558 };
00559 
00560 #ifdef JOT_NEEDS_DOUBLE_STAR_EXPLICIT
00561 inline XYvec operator *(double s, const XYvec& p) { return p * s;}
00562 #endif
00563 
00564 /*!
00565  *  \brief A point in XY coordinates.
00566  *
00567  */
00568 class XYpt : public Point2<XYpt, XYvec> {
00569    
00570    protected:
00571    
00572       static CXYpt _origin;
00573 
00574    public:
00575    
00576       //! \name Constructors
00577       //@{
00578          
00579       XYpt() { }
00580       explicit XYpt(double s) : Point2<XYpt,XYvec>(s) { }
00581       XYpt(double x, double y):Point2<XYpt,XYvec>(x,y) { }
00582       XYpt(CNDCpt& );
00583       XYpt(CPIXEL& );
00584       XYpt(CWpt  & );
00585       inline XYpt(CXYline& , CXYline& );
00586       inline XYpt(CXYline& , CXYpt  & );
00587       
00588       //@}
00589       
00590       static CXYpt& Origin() { return XYpt::_origin; }
00591    
00592 };
00593 
00594 #ifdef JOT_NEEDS_DOUBLE_STAR_EXPLICIT
00595 inline XYpt operator *(double s, const XYpt& p) { return p * s;}
00596 #endif
00597 
00598 /*!
00599  *  \brief A line in XY coordinates.
00600  *
00601  */
00602 class XYline : public Line<XYline, XYpt, XYvec> {
00603    
00604    public:
00605    
00606       //! \name Constructors
00607       //@{
00608    
00609       XYline() { }
00610       XYline(CXYpt& p,  CXYvec& v) : Line<XYline,XYpt,XYvec>(p,v)  {}
00611       XYline(CXYpt& p1, CXYpt & p2): Line<XYline,XYpt,XYvec>(p1,p2) {}
00612       
00613       //@}
00614 
00615 };
00616 
00617 /*!
00618  *  \brief A list of points in XY coordinates.
00619  *
00620  */
00621 class XYpt_list : public Point2list<XYpt_list,XYpt,XYvec,XYline> {
00622    
00623    public:
00624    
00625       //! \name Constructors
00626       //@{
00627    
00628       XYpt_list(int m=0)
00629          : Point2list<XYpt_list,XYpt,XYvec,XYline>(m) {}
00630       XYpt_list(const Point2list<XYpt_list,XYpt,XYvec,XYline>& p)
00631          : Point2list<XYpt_list,XYpt,XYvec,XYline>(p) {}
00632       
00633       //@}
00634       
00635       //! \name Projection Functions
00636       //@{
00637       
00638       void project_to_plane(CWplane& P, Wpt_list& pts) const {
00639          pts.clear();
00640          if (!empty()) pts.realloc(num());
00641          for (int i=0; i<_num; i++)
00642             pts += Wpt(P, Wline(_array[i]));
00643          pts.update_length();
00644       }
00645       
00646       //@}
00647    
00648 };
00649 
00650 inline XYpt::XYpt(CXYline& a, CXYline& b) {(*this) = a.intersect(b);}
00651 inline XYpt::XYpt(CXYline& a, CXYpt  & b) {(*this) = a.project(b);}
00652 
00653 //@}
00654 
00655 } // namespace mlib
00656 
00657 namespace mlib {
00658 
00659 //! \addtogroup group_ndcz_coordinate_system
00660 //! NDCZ coordinates : 3D normalized device coordinates
00661 //!
00662 //! Normalized device coordinates that range
00663 //! from -1 to 1 in the shorter window dimension,
00664 //! and from -a to a in the longer dimension,
00665 //! where 'a' is the aspect ratio, i.e. the ratio
00666 //! of the window's longer side to its shortest one.
00667 //! The 3rd coordinate gives 'depth', as computed
00668 //! by the camera's projection matrix.
00669 //@{
00670 
00671 /*!
00672  *  \brief A vector in NDCZ coordinates.
00673  *
00674  */
00675 class NDCZvec : public Vec3<NDCZvec> {
00676    
00677    protected:
00678    
00679       static CNDCZvec _null_vec;
00680       static CNDCZvec _x_axis;
00681       static CNDCZvec _y_axis;
00682       static CNDCZvec _z_axis;
00683 
00684    public:
00685    
00686       //! \name Constructors
00687       //@{
00688    
00689       NDCZvec() { }
00690       NDCZvec(double x, double y, double z):Vec3<NDCZvec>(x,y,z) { }
00691       NDCZvec(CNDCvec& );
00692       NDCZvec(CXYvec& );
00693       NDCZvec(CWvec&v, CWtransf& obj_to_ndc_der);
00694       NDCZvec(CVEXEL& );
00695       
00696       //@}
00697       
00698       //! \name Vector Operations
00699       //@{
00700       
00701       //! \brief Computes an arbitrary vector that is perpendicular to this one
00702       //! and that lies in the xy-plane.
00703       //! 
00704       //! Differs from the perpend() function becayse it only takes the x and y
00705       //! coordinates into account (i.e. it ignores depth).
00706       NDCZvec perpendicular() const { return NDCZvec(-_y, _x, 0); }
00707       
00708       //@}
00709       
00710       //! \name Vector Property Queries
00711       //@{
00712       
00713       //! \brief Computes the length of the vector in the xy-plane (i.e. ignores
00714       //! depth).
00715       double  planar_length() const { return sqrt(_x*_x+_y*_y); }
00716       
00717       //@}
00718       
00719       static CNDCZvec& null() { return NDCZvec::_null_vec; }
00720       static CNDCZvec&    X() { return NDCZvec::_x_axis; }
00721       static CNDCZvec&    Y() { return NDCZvec::_y_axis; }
00722       static CNDCZvec&    Z() { return NDCZvec::_z_axis; }
00723 
00724 };
00725 
00726 #ifdef JOT_NEEDS_DOUBLE_STAR_EXPLICIT
00727 inline NDCZvec operator *(double s, const NDCZvec& p) { return p * s;}
00728 #endif
00729 
00730 /*!
00731  *  \brief A point in NDCZ coordinates.
00732  *
00733  */
00734 class NDCZpt : public Point3<NDCZpt, NDCZvec> {
00735    
00736    protected:
00737    
00738       static CNDCZpt _origin;
00739 
00740    public:
00741    
00742       //! \name Constructors
00743       //@{
00744    
00745       NDCZpt() { }
00746       explicit NDCZpt(double s) : Point3<NDCZpt,NDCZvec>(s) { }
00747       NDCZpt(double x, double y, double z):Point3<NDCZpt,NDCZvec>(x,y,z) { }
00748       NDCZpt(CWpt& w);
00749       NDCZpt(CWpt& w, CWtransf& PM);
00750       NDCZpt(CXYpt& );
00751       NDCZpt(CNDCpt& );
00752       NDCZpt(CPIXEL& );
00753       
00754       //@}
00755       
00756       //! \name Two Point Operations
00757       //@{
00758       
00759       //! \brief Return the distance between NDCZpts, ignoring z-coord.
00760       double planar_length(CNDCZpt& p) const {
00761          double dx = _x - p._x, dy = _y - p._y;
00762          return sqrt(dx*dx + dy*dy);
00763       }
00764       
00765       //@}
00766       
00767       //! \name Misc. Functions
00768       //@{
00769       
00770       //! \brief Project to an XYpt_list, provided all points lie in
00771       //! the view frustum. Assumes Wpts are not in "object
00772       //! space."
00773       bool in_frustum() const;
00774       
00775       //@}
00776       
00777       static CNDCZpt& Origin() { return NDCZpt::_origin; }
00778 
00779 };
00780 
00781 /*!
00782  *  \brief A list of points in NDCZ coordinates.
00783  *
00784  *  \remark This class is very similar to the Pointlist class.  However, there
00785  *  are some fundamental differences in how it handles distances.  Specifically,
00786  *  it measures distances in 2D (XY) coordinates, rather than 3D (XY + depth)
00787  *  coordinates.  Because NDCZpt is based on the Point3 class, the Pointlist
00788  *  class can't be used as a base because that would force distances to be
00789  *  computed in 3D rather than the desired 2D.  Hence, a good chunk of the
00790  *  functional from Pointlist is duplicates here.
00791  *
00792  */
00793 class NDCZpt_list : public ARRAY<NDCZpt> {
00794    
00795    protected:
00796    
00797       ARRAY<double>    _partial_length;
00798 
00799    public:
00800    
00801       //! \name Constructors
00802       //@{
00803    
00804       NDCZpt_list(int max=0)              : ARRAY<NDCZpt>(max) {}
00805       NDCZpt_list(const ARRAY<NDCZpt>& p) : ARRAY<NDCZpt>(p)   {}
00806       
00807       //@}
00808       
00809       //! \name Segment Accessor Functions
00810       //@{
00811    
00812       //! Gets a vector pointing from the start point to the end point of the
00813       //! \p i<sup>th</sup> segment.
00814       NDCZvec segment       (int i) const { return _array[i+1]-_array[i];}
00815       //! Gets the length of the \p i<sup>th</sup> segment.
00816       double  segment_length(int i) const { return segment(i).length(); }
00817    
00818       //! Return segment \p i with 0 depth component:
00819       NDCZvec xy_seg(int i) const {
00820          NDCZvec ret = segment(i);
00821          ret[2] = 0;
00822          return ret;
00823       }
00824       double xy_len(int i) const { return xy_seg(i).length(); }
00825       
00826       //@}
00827       
00828       //! \name Interpolation Functions
00829       //@{
00830    
00831       //! \brief Parameter s should lie in the range [0,1]. Returns the
00832       //! corresponding segment index, and the paramter t varying
00833       //! from 0 to 1 along that segment.
00834       //!
00835       //! \note Progress along the polyline is measured just in X and Y, not Z.
00836       void   interpolate_length(double s, int& seg, double& t)              const;
00837    
00838       //! \brief Given interpolation parameter s varying from 0 to 1
00839       //! along the polyline, return the corresponding point,
00840       //! and optionally the tangent, segment index, and segment
00841       //! paramter there:
00842       //!
00843       //! \note Progress along the polyline is measured just in X and Y, not Z.
00844       NDCZpt interpolate(double s, NDCZvec *tan=0, int*segp=0, double*tp=0) const;
00845       
00846       //@}
00847       
00848       //! \name Length Functions
00849       //@{
00850    
00851       //! \brief This function must be called for interpolation routines to work.
00852       //! \note Policy on measuring length: we ignore the z component.
00853       void update_length() {
00854          double len = 0;
00855          _partial_length.clear();
00856          if (_num > 0)
00857             _partial_length.realloc(_num);
00858          _partial_length += 0;
00859          for ( int i=1; i< _num; i++ ) {
00860             len += xy_len(i-1);
00861             _partial_length += len;
00862          }
00863       }
00864       double partial_length(int i) const {
00865          return _partial_length.valid_index(i) ? _partial_length[i] : 0;
00866       }
00867    
00868       double length() const {
00869          return _partial_length.empty() ? 0 : _partial_length.last();
00870       }
00871       
00872       //@}
00873    
00874       //! \name Misc. Functions
00875       //@{
00876          
00877       NDCZvec  tan(int i)      const;
00878    
00879       NDCZpt   average () const {
00880          NDCZpt sum; 
00881          for(int i=0;i<num();i++) sum=sum+(*this)[i];
00882          return sum/(num() ? num():1); 
00883       }
00884       
00885       //@}
00886 
00887 };
00888 
00889 /*!
00890  *  \brief A list of vectors in NDCZ coordinates.
00891  *
00892  *  \question Is this class done?
00893  *  \question Is _partial_length even necessary?
00894  *
00895  */
00896 class NDCZvec_list : public ARRAY<NDCZvec> {
00897    
00898    protected:
00899    
00900       ARRAY<double>    _partial_length;
00901 
00902    public:
00903    
00904       //! \name Constructors
00905       //@{
00906    
00907       NDCZvec_list(int max=0)             :ARRAY<NDCZvec>(max) { }
00908       NDCZvec_list(const ARRAY<NDCZvec>& p) :ARRAY<NDCZvec>(p) { }
00909       
00910       //@}
00911       
00912       //! \name Misc. Functions
00913       //@{
00914       
00915       NDCZvec   average () const {
00916          NDCZvec sum;
00917          for(int i=0;i<num();i++) sum=sum + (*this)[i];
00918          return sum/(num() ? num():1); 
00919       }
00920       
00921       //@}
00922 
00923 };
00924 
00925 NDCZvec normal_to_ndcz(CWpt& p, CWvec& world_normal);
00926 
00927 //@}
00928 
00929 } // namespace mlib
00930 
00931 namespace mlib {
00932 
00933 //! \addtogroup group_ndc_coordinate_system
00934 //! Normalized device coordinates that range
00935 //! from -1 to 1 in the shorter window dimension,
00936 //! and from -a to a in the longer dimension,
00937 //! where 'a' is the aspect ratio, i.e. the ratio
00938 //! of the window's longer side to its shortest one.
00939 //@{
00940 
00941 /*!
00942  *  \brief A vector in NDC coordinates.
00943  *
00944  */
00945 class NDCvec : public Vec2<NDCvec> {
00946    
00947    protected:
00948    
00949       static CNDCvec _null_vec;
00950       static CNDCvec _x_axis;
00951       static CNDCvec _y_axis;
00952 
00953    public:
00954    
00955       //! \name Constructors
00956       //@{
00957    
00958       NDCvec() { }
00959       NDCvec(double x, double y):Vec2<NDCvec>(x,y) { }
00960       NDCvec(CXYvec& );
00961       NDCvec(CVEXEL& );
00962       NDCvec(CNDCZvec& v): Vec2<NDCvec>(v[0], v[1]) { };
00963       
00964       //@}
00965       
00966       //! \name Vector Operations
00967       //@{
00968       
00969       //! \question Isn't this the same as the Vec2 perpend() function?
00970       NDCvec perpendicular() const { return NDCvec(-_y, _x); }
00971       
00972       //@}
00973       
00974       static CNDCvec& null() { return NDCvec::_null_vec; }
00975       static CNDCvec&    X() { return NDCvec::_x_axis; }
00976       static CNDCvec&    Y() { return NDCvec::_y_axis; }
00977 
00978 };
00979 
00980 #ifdef JOT_NEEDS_DOUBLE_STAR_EXPLICIT
00981 inline NDCvec operator *(double s, const NDCvec& p) { return p * s;}
00982 #endif
00983 
00984 /*!
00985  *  \brief A point in NDC coordinates.
00986  *
00987  */
00988 class NDCpt : public Point2<NDCpt, NDCvec> {
00989    
00990    protected:
00991    
00992       static CNDCpt _origin;
00993 
00994    public:
00995    
00996       //! \name Constructors
00997       //@{
00998    
00999       NDCpt() { }
01000       explicit NDCpt(double s) : Point2<NDCpt,NDCvec>(s) { }
01001       NDCpt(double x, double y):Point2<NDCpt,NDCvec>(x,y) { }
01002       NDCpt(CNDCZpt& n):Point2<NDCpt,NDCvec>(n[0],n[1]) { }
01003       NDCpt(CWpt& w);
01004       NDCpt(CXYpt& );
01005       NDCpt(CPIXEL& p) { *this = XYpt(p); }
01006       
01007       //@}
01008       
01009       static CNDCpt& Origin() { return NDCpt::_origin; }
01010       
01011 };
01012 
01013 /*!
01014  *  \brief A line in NDC coordinates.
01015  *
01016  */
01017 class NDCline : public Line<NDCline, NDCpt, NDCvec> {
01018    
01019    public:
01020    
01021       //! \name Constructors
01022       //@{
01023  
01024       NDCline() {}
01025       NDCline(CNDCpt& p,  CNDCvec& v) : Line<NDCline,NDCpt,NDCvec>(p,v)   {}
01026       NDCline(CNDCpt& p1, CNDCpt& p2) : Line<NDCline,NDCpt,NDCvec>(p1,p2) {}
01027       
01028       //@}
01029 
01030 };
01031 
01032 /*!
01033  *  \brief A list of points in NDC coordinates.
01034  *
01035  */
01036 class NDCpt_list : public Point2list<NDCpt_list,NDCpt,NDCvec,NDCline> {
01037    
01038    public:
01039    
01040       //! \name Constructors
01041       //@{
01042    
01043       NDCpt_list(int m=0)
01044          : Point2list<NDCpt_list,NDCpt,NDCvec,NDCline>(m) {}
01045       NDCpt_list(const Point2list<NDCpt_list,NDCpt,NDCvec,NDCline>& N)
01046          : Point2list<NDCpt_list,NDCpt,NDCvec,NDCline>(N) { update_length(); }
01047       NDCpt_list(CXYpt_list&   X)
01048          : Point2list<NDCpt_list,NDCpt,NDCvec,NDCline>(0) { *this = X; }
01049       NDCpt_list(CNDCZpt_list& N)
01050          : Point2list<NDCpt_list,NDCpt,NDCvec,NDCline>(0) { *this = N; }
01051       NDCpt_list(CPIXEL_list&  P)
01052          : Point2list<NDCpt_list,NDCpt,NDCvec,NDCline>(0) { *this = P; }
01053          
01054       //@}
01055       
01056       //! \name Overloaded Assignment Operators
01057       //@{
01058       
01059       NDCpt_list& operator=(CXYpt_list&   X);
01060       NDCpt_list& operator=(CNDCZpt_list& N);
01061       NDCpt_list& operator=(CPIXEL_list&  P);
01062       
01063       //@}
01064       
01065       //! \name Projection Functions
01066       //@{
01067       
01068       void project_to_plane(CWplane& P, Wpt_list& pts) const {
01069          pts.clear();
01070          if (!empty()) pts.realloc(num());
01071          for (int i=0; i<_num; i++)
01072             pts += Wpt(P, Wline(_array[i]));
01073          pts.update_length();
01074       }
01075       
01076       //@}
01077 
01078 };
01079 
01080 //@}
01081 
01082 } // namespace mlib
01083 
01084 namespace mlib {
01085 
01086 //! \addtogroup group_pixel_coordinate_system
01087 //! Corresponds to GL-style pixels coords:
01088 //! lower left corner is (0,0)
01089 //! upper right is (width-1, height-1)
01090 //@{
01091 
01092 /*!
01093  *  \brief A vector in pixel coordinates.
01094  *
01095  */
01096 class VEXEL : public Vec2<VEXEL> {
01097    
01098    protected:
01099    
01100       static CVEXEL _null_vec;
01101       static CVEXEL _x_axis;
01102       static CVEXEL _y_axis;
01103 
01104    public:
01105    
01106       //! \name Constructors
01107       //@{
01108    
01109       VEXEL() { }
01110       VEXEL(double x, double y):Vec2<VEXEL>(x,y) { }
01111       VEXEL(CXYvec& );
01112       VEXEL(CNDCvec& );
01113       VEXEL(CWpt& , CWvec& );
01114       
01115       //@}
01116       
01117       static CVEXEL& null() { return VEXEL::_null_vec; }
01118       static CVEXEL&    X() { return VEXEL::_x_axis; }
01119       static CVEXEL&    Y() { return VEXEL::_y_axis; }
01120 
01121 };
01122 
01123 #ifdef JOT_NEEDS_DOUBLE_STAR_EXPLICIT
01124 inline VEXEL operator *(double s, const VEXEL& p) { return p * s;}
01125 #endif
01126 
01127 /*!
01128  *  \brief A point in pixel coordinates.
01129  *
01130  */
01131 class PIXEL : public Point2<PIXEL, VEXEL> {
01132    
01133    protected:
01134    
01135       static CPIXEL _origin;
01136 
01137    public:
01138    
01139       //! \name Constructors
01140       //@{
01141  
01142       PIXEL() { }
01143       explicit PIXEL(double s) : Point2<PIXEL,VEXEL>(s) { }
01144       PIXEL(double x, double y):Point2<PIXEL,VEXEL>(x,y) { }
01145       PIXEL(CXYpt& );
01146       PIXEL(CWpt& w) { *this = XYpt(w); }
01147       
01148       //@}
01149       
01150       static CPIXEL& Origin() { return PIXEL::_origin; }
01151 
01152 };
01153 
01154 /*!
01155  *  \brief A line in pixel coordinates.
01156  *
01157  */
01158 class PIXELline : public Line<PIXELline, PIXEL, VEXEL> {
01159    
01160    public:
01161    
01162       //! \name Constructors
01163       //@{
01164    
01165       PIXELline() {}
01166       PIXELline(CPIXEL& p,  CVEXEL&  v) : Line<PIXELline,PIXEL,VEXEL>(p,v)   {}
01167       PIXELline(CPIXEL& p1, CPIXEL& p2) : Line<PIXELline,PIXEL,VEXEL>(p1,p2) {}
01168       
01169       //@}
01170 
01171 };
01172 
01173 /*!
01174  *  \brief A list of points in pixel coordinates.
01175  *
01176  */
01177 class PIXEL_list : public Point2list<PIXEL_list,PIXEL,VEXEL,PIXELline> {
01178    
01179    public:
01180    
01181       //! \name Constructors
01182       //@{
01183       
01184       PIXEL_list(int n=0)
01185          : Point2list<PIXEL_list,PIXEL,VEXEL,PIXELline>(n) {}
01186       PIXEL_list(const Point2list<PIXEL_list,PIXEL,VEXEL,PIXELline>& P)
01187          : Point2list<PIXEL_list,PIXEL,VEXEL,PIXELline>(P) { update_length(); }
01188       PIXEL_list(CWpt_list&    W)
01189          : Point2list<PIXEL_list,PIXEL,VEXEL,PIXELline>(0) { *this = W; }
01190       PIXEL_list(CXYpt_list&   X)
01191          : Point2list<PIXEL_list,PIXEL,VEXEL,PIXELline>(0) { *this = X; }
01192       PIXEL_list(CNDCpt_list&  N)
01193          : Point2list<PIXEL_list,PIXEL,VEXEL,PIXELline>(0) { *this = N; }
01194       PIXEL_list(CNDCZpt_list& N)
01195          : Point2list<PIXEL_list,PIXEL,VEXEL,PIXELline>(0) { *this = N; }
01196          
01197       //@}
01198       
01199       //! \name Overloaded Assignment Operators
01200       //@{
01201       
01202       PIXEL_list& operator=(CWpt_list&    X);
01203       PIXEL_list& operator=(CXYpt_list&   X);
01204       PIXEL_list& operator=(CNDCpt_list&  N);
01205       PIXEL_list& operator=(CNDCZpt_list& N);
01206       
01207       //@}
01208       
01209       //! \name Projection Functions
01210       //@{
01211       
01212       void project_to_plane(CWplane& P, Wpt_list& pts) const {
01213          pts.clear();
01214          if (!empty()) pts.realloc(num());
01215          for (int i=0; i<_num; i++)
01216             pts += Wpt(P, Wline(_array[i]));
01217          pts.update_length();
01218       }
01219       
01220       //@}
01221 
01222 };
01223 
01224 //@}
01225 
01226 } // namespace mlib
01227 
01228 namespace mlib {
01229 
01230 //! \addtogroup group_uv_coordinate_system
01231 //! UV coordinates : -1 to 1 normalized coordinates
01232 //@{
01233 
01234 /*!
01235  *  \brief A vector in UV coordinates.
01236  *
01237  */
01238 class UVvec : public Vec2<UVvec> {
01239    
01240    protected:
01241    
01242       static CUVvec _null_vec;
01243       static CUVvec _u_dir;
01244       static CUVvec _v_dir;
01245 
01246    public:
01247    
01248       //! \name Constructors
01249       //@{
01250       
01251       UVvec() {}
01252       UVvec(double u, double v) : Vec2<UVvec>(u,v) {}
01253       
01254       //@}
01255       
01256       static CUVvec& null() { return UVvec::_null_vec; }
01257       static CUVvec&    U() { return UVvec::_u_dir; }
01258       static CUVvec&    V() { return UVvec::_v_dir; }
01259 
01260 };
01261 
01262 #ifdef JOT_NEEDS_DOUBLE_STAR_EXPLICIT
01263 inline UVvec operator*(double s, const UVvec& p) { return p * s;}
01264 #endif
01265 
01266 /*!
01267  *  \brief A point in UV coordinates.
01268  *
01269  */
01270 class UVpt : public Point2<UVpt, UVvec> {
01271    
01272    protected:
01273    
01274       static CUVpt _origin;
01275 
01276    public:
01277    
01278       //! \name Constructors
01279       //@{
01280       
01281       UVpt() {}
01282       explicit UVpt(double s) : Point2<UVpt,UVvec>(s) { }
01283       UVpt(double u, double v) : Point2<UVpt,UVvec>(u,v) {}
01284       inline UVpt(CUVline&, CUVline&);
01285       inline UVpt(CUVline&, CUVpt&);
01286       
01287       //@}
01288       
01289       static CUVpt& Origin() { return UVpt::_origin; }
01290 
01291 };
01292 
01293 #ifdef JOT_NEEDS_DOUBLE_STAR_EXPLICIT
01294 inline UVpt operator *(double s, const UVpt& p) { return p * s;}
01295 #endif
01296 
01297 /*!
01298  *  \brief A line in UV coordinates.
01299  *
01300  */
01301 class UVline : public Line<UVline, UVpt, UVvec> {
01302    
01303    public:
01304    
01305       //! \name Constructors
01306       //@{
01307    
01308       UVline() {}
01309       UVline(CUVpt& p,  CUVvec& v)  : Line<UVline,UVpt,UVvec>(p,v)   {}
01310       UVline(CUVpt& p1, CUVpt & p2) : Line<UVline,UVpt,UVvec>(p1,p2) {}
01311       
01312       //@}
01313 
01314 };
01315 
01316 /*!
01317  *  \brief A list of points in UV coordinates.
01318  *
01319  */
01320 class UVpt_list : public Point2list<UVpt_list,UVpt,UVvec,UVline> {
01321    
01322    public:
01323    
01324       //! \name Constructors
01325       //@{
01326    
01327       UVpt_list(int m=0)
01328          : Point2list<UVpt_list,UVpt,UVvec,UVline>(m) {}
01329       UVpt_list(const Point2list<UVpt_list,UVpt,UVvec,UVline>& p)
01330          : Point2list<UVpt_list,UVpt,UVvec,UVline>(p) {}
01331       
01332       //@}
01333 
01334 };
01335 
01336 inline UVpt::UVpt(CUVline& a, CUVline& b) {(*this) = a.intersect(b);}
01337 inline UVpt::UVpt(CUVline& a, CUVpt  & b) {(*this) = a.project(b);}
01338 
01339 //@}
01340 
01341 } // namespace mlib
01342 
01343 namespace mlib {
01344 
01345 class EDGElist;
01346 
01347 //! \brief Shortcut for const EDGElist.
01348 //! \relates EDGElist
01349 typedef const EDGElist CEDGElist;
01350 
01351 /*!
01352  *  \brief A list of edges in World coordinates.
01353  *
01354  *  Stores a list of vertices as points and a list of pairs of indices into the
01355  *  vertex list (representing edges).
01356  *
01357  */
01358 class EDGElist {
01359    
01360    protected:
01361    
01362       Wpt_list      _verts;
01363       ARRAY<int>    _start;
01364       ARRAY<int>    _end;
01365       
01366    public:
01367    
01368       //! \name Constructors
01369       //@{
01370    
01371       EDGElist(CWpt_list& verts) :_verts(verts)    {}
01372       EDGElist() : _verts(0), _start(0), _end(0)   {}
01373       
01374       //@}
01375       
01376       //! \name Edge Accessor Functions
01377       //@{
01378       
01379       void add_edge(int i, int j)      { _start += i; _end += j;}
01380       
01381       void edge(int edge, Wpt& s, Wpt& e) const
01382          { s = _verts[_start[edge]]; e= _verts[_end[edge]]; }
01383       
01384       CWpt& operator()(int edge, int num) const 
01385          { return num == 0 ? _verts[_start[edge]] : _verts[_end[edge]];}
01386       
01387       void reset   (CWpt_list& verts)  { reset(); _verts = verts; }
01388       void reset   ()                  { _verts.clear(); _start.clear(); _end.clear();}
01389       
01390       //@}
01391       
01392       //! \name EDGElist Operations
01393       //@{
01394       
01395       void xform   (CWtransf& t)       { _verts.xform(t);}
01396       
01397       //@}
01398       
01399       //! \name EDGElist Property Queries
01400       //@{
01401          
01402       int       num     () const       { return _start.num(); }
01403       
01404       //@}
01405 
01406 };
01407 
01408 } // namespace mlib
01409 
01410 namespace mlib {
01411 
01412 //---------------------------------------------------
01413 //  Well-known items like 4x4 identity transform.
01414 //---------------------------------------------------
01415 extern CWtransf Identity;
01416 
01417 } // namespace mlib
01418 
01419 //---------------------------------------------------
01420 //  Conversion functions.
01421 //---------------------------------------------------
01422 extern mlib::Wpt  (*XYtoW_1 )(mlib::CXYpt& , mlib::CWpt& ) ;
01423 extern mlib::Wpt  (*XYtoW_2 )(mlib::CXYpt& , double) ;
01424 extern mlib::Wpt  (*XYtoW_3 )(mlib::CXYpt& ) ;
01425 extern mlib::Wvec (*XYtoWvec)(mlib::CXYpt& ) ;
01426 extern mlib::XYpt (*WtoXY   )(mlib::CWpt & ) ;
01427 extern void (*VIEW_SIZE)(int& , int& ) ;
01428 extern void (*VIEW_PIXELS)(double& , mlib::NDCpt& ) ;
01429 extern double (*VIEW_ASPECT)() ;
01430 extern mlib::CWtransf& (*VIEW_NDC_TRANS)() ;
01431 extern mlib::CWtransf& (*VIEW_NDC_TRANS_INV)() ;
01432 #if defined(MLIB_STANDALONE) || defined(DEV_STANDALONE)
01433 mlib::Wpt  (*XYtoW_1 )(mlib::CXYpt& , mlib::CWpt& ) = 0;
01434 mlib::Wpt  (*XYtoW_2 )(mlib::CXYpt& , double) = 0;
01435 mlib::Wpt  (*XYtoW_3 )(mlib::CXYpt& ) = 0;
01436 mlib::Wvec (*XYtoWvec)(mlib::CXYpt& ) = 0;
01437 mlib::XYpt (*WtoXY   )(mlib::CWpt & ) = 0;
01438 void (*VIEW_SIZE)(int& , int& ) = 0;
01439 double (*VIEW_ASPECT)() = 0;
01440 mlib::CWtransf& (*VIEW_NDC_TRANS)() = 0;
01441 mlib::CWtransf& (*VIEW_NDC_TRANS_INV)() = 0;
01442 void (*VIEW_PIXELS)(double& , mlib::NDCpt& ) = 0;
01443 inline mlib::Wtransf RET_IDENTITY() { return mlib::Identity; }
01444 #endif
01445 
01446 namespace mlib {
01447 
01448 //---------------------------------------------------
01449 //  Convenience functions.
01450 //---------------------------------------------------
01451 
01452 //! \brief Given point p in world space and pixel length r,
01453 //! return the world space length of a segment passing
01454 //! through p, parallel to the film plane, with pixel
01455 //! length r.
01456 inline double
01457 world_length(CWpt& p, double r)
01458 {
01459    return 2*(p - Wpt(XYpt(PIXEL(p) + VEXEL(r/2,0)), p)).length();
01460 }
01461 
01462 //! \brief Same as world_length(CWpt& p, double r), but for object-space
01463 //! point o, with transform M from object to world and its inverse I.
01464 inline double
01465 obj_length(CWpt& o, double r, CWtransf& M, CWtransf& I)
01466 {
01467    Wpt w = M*o;
01468    return (o - I*Wpt(XYpt(PIXEL(w)+VEXEL(r,0)), w)).length();
01469 }
01470 
01471 } // namespace mlib
01472 
01473 #endif // POINTS_H_IS_INCLUDED
01474 
01475 /* end of file points.H */

Generated on Mon Sep 18 11:39:33 2006 for jot by  doxygen 1.4.4