00001
00002 #ifndef vgl_homg_point_2d_h_
00003 #define vgl_homg_point_2d_h_
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <vgl/vgl_vector_2d.h>
00020 #include <vgl/vgl_point_2d.h>
00021 #include <vgl/vgl_fwd.h>
00022 #include <vcl_iosfwd.h>
00023 #include <vcl_cassert.h>
00024
00025
00026 template <class T>
00027 class vgl_homg_point_2d
00028 {
00029
00030 T x_;
00031 T y_;
00032 T w_;
00033
00034 public:
00035
00036
00037
00038
00039 inline vgl_homg_point_2d() : x_(0), y_(0), w_((T)1) {}
00040
00041
00042 inline vgl_homg_point_2d(T px, T py, T pw = (T)1)
00043 : x_(px), y_(py), w_(pw) {}
00044
00045
00046 inline vgl_homg_point_2d(const T v[3]) : x_(v[0]), y_(v[1]), w_(v[2]) {}
00047
00048
00049 inline vgl_homg_point_2d(vgl_vector_2d<T>const& v) : x_(v.x()), y_(v.y()), w_(0) {}
00050
00051
00052 inline explicit vgl_homg_point_2d(vgl_point_2d<T> const& p)
00053 : x_(p.x()), y_(p.y()), w_((T)1) {}
00054
00055
00056 vgl_homg_point_2d(vgl_homg_line_2d<T> const& l1,
00057 vgl_homg_line_2d<T> const& l2);
00058
00059 #if 0
00060
00061 inline vgl_homg_point_2d(const vgl_homg_point_2d<T>& p)
00062 : x_(p.x()), y_(p.y()), w_(p.w()) {}
00063
00064
00065 inline ~vgl_homg_point_2d() {}
00066
00067
00068 inline vgl_homg_point_2d<T>& operator=(vgl_homg_point_2d<T>const& p)
00069 {
00070 set(p.x(),p.y(),p.w());
00071 return *this;
00072 }
00073 #endif
00074
00075
00076 inline bool operator==(vgl_homg_point_2d<T> const& p) const
00077 {
00078 return (this==&p) ||
00079 (x()*p.w()==w()*p.x() && y()*p.w()==w()*p.y() && y()*p.x()==x()*p.y());
00080 }
00081
00082 inline bool operator!=(vgl_homg_point_2d<T> const& other)const{return !operator==(other);}
00083
00084
00085
00086 inline T x() const { return x_; }
00087 inline T y() const { return y_; }
00088 inline T w() const { return w_; }
00089
00090
00091
00092 inline void set(T px, T py, T pw = (T)1)
00093 { x_ = px, y_ = py, w_ = pw; }
00094
00095 inline void set(T const p[3]) { x_ = p[0]; y_ = p[1]; w_ = p[2]; }
00096
00097
00098
00099 inline bool ideal(T tol = (T)0) const
00100 {
00101 #define vgl_Abs(x) (x<0?-x:x) // avoid #include of vcl_cmath.h AND vcl_cstdlib.h
00102 return vgl_Abs(w()) <= tol * vgl_Abs(x()) ||
00103 vgl_Abs(w()) <= tol * vgl_Abs(y());
00104 #undef vgl_Abs
00105 }
00106 };
00107
00108
00109
00110
00111
00112 template <class T>
00113 vcl_ostream& operator<<(vcl_ostream& s, vgl_homg_point_2d<T> const& p);
00114
00115
00116
00117 template <class T>
00118 vcl_istream& operator>>(vcl_istream& s, vgl_homg_point_2d<T>& p);
00119
00120
00121
00122
00123
00124
00125 template <class T> inline
00126 bool is_ideal(vgl_homg_point_2d<T> const& p, T tol=(T)0){return p.ideal(tol);}
00127
00128
00129
00130
00131 template <class T> inline
00132 vgl_vector_2d<T> operator-(vgl_homg_point_2d<T> const& p1,
00133 vgl_homg_point_2d<T> const& p2)
00134 {
00135 assert(p1.w() && p2.w());
00136 return vgl_vector_2d<T>(p1.x()/p1.w()-p2.x()/p2.w(),
00137 p1.y()/p1.w()-p2.y()/p2.w());
00138 }
00139
00140
00141
00142
00143
00144 template <class T> inline
00145 vgl_homg_point_2d<T> operator+(vgl_homg_point_2d<T> const& p,
00146 vgl_vector_2d<T> const& v)
00147 { return vgl_homg_point_2d<T>(p.x()+v.x()*p.w(), p.y()+v.y()*p.w(), p.w()); }
00148
00149
00150
00151
00152 template <class T> inline
00153 vgl_homg_point_2d<T>& operator+=(vgl_homg_point_2d<T>& p,
00154 vgl_vector_2d<T> const& v)
00155 { p.set(p.x()+v.x()*p.w(), p.y()+v.y()*p.w(), p.w()); return p; }
00156
00157
00158
00159 template <class T> inline
00160 vgl_homg_point_2d<T> operator-(vgl_homg_point_2d<T> const& p,
00161 vgl_vector_2d<T> const& v)
00162 { return p + (-v); }
00163
00164
00165
00166 template <class T> inline
00167 vgl_homg_point_2d<T>& operator-=(vgl_homg_point_2d<T>& p,
00168 vgl_vector_2d<T> const& v)
00169 { return p += (-v); }
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191 template <class T>
00192 double cross_ratio(vgl_homg_point_2d<T>const& p1, vgl_homg_point_2d<T>const& p2,
00193 vgl_homg_point_2d<T>const& p3, vgl_homg_point_2d<T>const& p4);
00194
00195
00196
00197 template <class T> inline
00198 bool collinear(vgl_homg_point_2d<T> const& p1,
00199 vgl_homg_point_2d<T> const& p2,
00200 vgl_homg_point_2d<T> const& p3)
00201 {
00202 return (p1.x()*p2.y()-p1.y()*p2.x())*p3.w()
00203 +(p3.x()*p1.y()-p3.y()*p1.x())*p2.w()
00204 +(p2.x()*p3.y()-p2.y()*p3.x())*p1.w()==0;
00205 }
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215 template <class T> inline
00216 double ratio(vgl_homg_point_2d<T> const& p1,
00217 vgl_homg_point_2d<T> const& p2,
00218 vgl_homg_point_2d<T> const& p3)
00219 { return (p3-p1)/(p2-p1); }
00220
00221
00222
00223
00224
00225
00226 template <class T> inline
00227 vgl_homg_point_2d<T> midpoint(vgl_homg_point_2d<T> const& p1,
00228 vgl_homg_point_2d<T> const& p2,
00229 T f = (T)0.5)
00230 { return p1 + f*(p2-p1); }
00231
00232
00233
00234
00235
00236
00237
00238 template <class T> inline
00239 vgl_homg_point_2d<T> centre(vgl_homg_point_2d<T> const& p1,
00240 vgl_homg_point_2d<T> const& p2)
00241 {
00242 return vgl_homg_point_2d<T>(p1.x()*p2.w() + p2.x()*p1.w(),
00243 p1.y()*p2.w() + p2.y()*p1.w(),
00244 p1.w()*p2.w()*2 );
00245 }
00246
00247
00248
00249
00250 template <class T> inline
00251 vgl_homg_point_2d<T> centre(vcl_vector<vgl_homg_point_2d<T> > const& v)
00252 {
00253 int n=v.size();
00254 assert(n>0);
00255 T x = 0, y = 0;
00256 for (int i=0; i<n; ++i) x+=v[i].x()/v[i].w(), y+=v[i].y()/v[i].w();
00257 return vgl_homg_point_2d<T>(x,y,(T)n);
00258 }
00259
00260 #define VGL_HOMG_POINT_2D_INSTANTIATE(T) extern "please include vgl/vgl_homg_point_2d.txx first"
00261
00262 #endif // vgl_homg_point_2d_h_