00001
00002 #ifndef vgl_homg_point_3d_h_
00003 #define vgl_homg_point_3d_h_
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <vgl/vgl_point_3d.h>
00020 #include <vgl/vgl_fwd.h>
00021 #include <vcl_iosfwd.h>
00022 #include <vcl_cassert.h>
00023
00024
00025 template <class Type>
00026 class vgl_homg_point_3d
00027 {
00028
00029 Type x_;
00030 Type y_;
00031 Type z_;
00032 Type w_;
00033
00034 public:
00035
00036
00037
00038
00039 inline vgl_homg_point_3d() : x_(0), y_(0), z_(0), w_((Type)1) {}
00040
00041
00042 inline vgl_homg_point_3d(Type px, Type py, Type pz, Type pw = (Type)1)
00043 : x_(px), y_(py), z_(pz), w_(pw) {}
00044
00045
00046 inline vgl_homg_point_3d(const Type v[4]) : x_(v[0]), y_(v[1]), z_(v[2]), w_(v[3]) {}
00047
00048
00049 inline vgl_homg_point_3d(vgl_vector_3d<Type>const& v) : x_(v.x()), y_(v.y()), z_(v.z()), w_(0) {}
00050
00051
00052 inline explicit vgl_homg_point_3d(vgl_point_3d<Type> const& p)
00053 : x_(p.x()), y_(p.y()), z_(p.z()), w_((Type)1) {}
00054
00055
00056 vgl_homg_point_3d(vgl_homg_plane_3d<Type> const& l1,
00057 vgl_homg_plane_3d<Type> const& l2,
00058 vgl_homg_plane_3d<Type> const& l3);
00059
00060 #if 0
00061
00062 inline vgl_homg_point_3d(const vgl_homg_point_3d<Type>& that)
00063 : x_(that.x()), y_(that.y()), z_(that.z()), w_(that.w()) {}
00064
00065
00066 inline ~vgl_homg_point_3d() {}
00067
00068
00069 inline vgl_homg_point_3d<Type>& operator=(const vgl_homg_point_3d<Type>& that)
00070 {
00071 set(that.x(),that.y(),that.z(),that.w());
00072 return *this;
00073 }
00074 #endif
00075
00076
00077 bool operator==(vgl_homg_point_3d<Type> const& other) const;
00078 inline bool operator!=(vgl_homg_point_3d<Type>const& other)const{return !operator==(other);}
00079
00080
00081
00082 inline Type x() const { return x_; }
00083 inline Type y() const { return y_; }
00084 inline Type z() const { return z_; }
00085 inline Type w() const { return w_; }
00086
00087
00088
00089 inline void set(Type px, Type py, Type pz, Type pw = (Type)1)
00090 { x_=px; y_=py; z_=pz; w_=pw; }
00091
00092 inline void set(Type const p[4]) { x_=p[0]; y_=p[1]; z_=p[2]; w_=p[3]; }
00093
00094
00095
00096 inline bool ideal(Type tol = (Type)0) const
00097 {
00098 #define vgl_Abs(x) (x<0?-x:x) // avoid #include of vcl_cmath.h AND vcl_cstdlib.h
00099 return vgl_Abs(w()) <= tol * vgl_Abs(x()) ||
00100 vgl_Abs(w()) <= tol * vgl_Abs(y()) ||
00101 vgl_Abs(w()) <= tol * vgl_Abs(z());
00102 #undef vgl_Abs
00103 }
00104
00105 inline bool get_nonhomogeneous(double& vx, double& vy, double& vz) const
00106 {
00107 if (w() == 0)
00108 {
00109 #ifdef DEBUG
00110 vcl_cerr << "vgl_homg_point_3d::get_nonhomogeneous - point at infinity\n";
00111 #endif
00112 return false;
00113 }
00114
00115 double hw = 1.0/w();
00116
00117 vx = x() * hw;
00118 vy = y() * hw;
00119 vz = z() * hw;
00120
00121 return true;
00122 }
00123
00124 inline bool rescale_w(Type new_w = Type(1))
00125 {
00126 if (w() == 0)
00127 return false;
00128
00129 x_ = x() * new_w / w();
00130 y_ = y() * new_w / w();
00131 z_ = z() * new_w / w();
00132 w_ = new_w;
00133
00134 return true;
00135 }
00136 };
00137
00138
00139
00140
00141
00142 template <class Type>
00143 vcl_ostream& operator<<(vcl_ostream& s, vgl_homg_point_3d<Type> const& p);
00144
00145
00146
00147 template <class Type>
00148 vcl_istream& operator>>(vcl_istream& s, vgl_homg_point_3d<Type>& p);
00149
00150
00151
00152
00153
00154
00155 template <class Type> inline
00156 bool is_ideal(vgl_homg_point_3d<Type> const& p, Type tol = (Type)0) { return p.ideal(tol); }
00157
00158
00159
00160 template <class Type> inline
00161 bool coplanar(vgl_homg_point_3d<Type> const& p1,
00162 vgl_homg_point_3d<Type> const& p2,
00163 vgl_homg_point_3d<Type> const& p3,
00164 vgl_homg_point_3d<Type> const& p4)
00165 {
00166 return ((p1.x()*p2.y()-p1.y()*p2.x())*p3.z()
00167 +(p3.x()*p1.y()-p3.y()*p1.x())*p2.z()
00168 +(p2.x()*p3.y()-p2.y()*p3.x())*p1.z())*p4.w()
00169 -((p4.x()*p1.y()-p4.y()*p1.x())*p2.z()
00170 +(p2.x()*p4.y()-p2.y()*p4.x())*p1.z()
00171 +(p1.x()*p2.y()-p1.y()*p2.x())*p4.z())*p3.w()
00172 +((p3.x()*p4.y()-p3.y()*p4.x())*p1.z()
00173 +(p1.x()*p3.y()-p1.y()*p3.x())*p4.z()
00174 +(p4.x()*p1.y()-p4.y()*p1.x())*p3.z())*p2.w()
00175 -((p2.x()*p3.y()-p2.y()*p3.x())*p4.z()
00176 +(p4.x()*p2.y()-p4.y()*p2.x())*p3.z()
00177 +(p3.x()*p4.y()-p3.y()*p4.x())*p2.z())*p1.w() == 0;
00178 }
00179
00180
00181
00182
00183 template <class Type> inline
00184 vgl_vector_3d<Type> operator-(vgl_homg_point_3d<Type> const& p1,
00185 vgl_homg_point_3d<Type> const& p2)
00186 {
00187 assert(p1.w() && p2.w());
00188 return vgl_vector_3d<Type>(p1.x()/p1.w()-p2.x()/p2.w(),
00189 p1.y()/p1.w()-p2.y()/p2.w(),
00190 p1.z()/p1.w()-p2.z()/p2.w());
00191 }
00192
00193
00194
00195
00196
00197 template <class Type> inline
00198 vgl_homg_point_3d<Type> operator+(vgl_homg_point_3d<Type> const& p,
00199 vgl_vector_3d<Type> const& v)
00200 {
00201 return vgl_homg_point_3d<Type>(p.x()+v.x()*p.w(),
00202 p.y()+v.y()*p.w(),
00203 p.z()+v.z()*p.w(), p.w());
00204 }
00205
00206
00207
00208
00209 template <class Type> inline
00210 vgl_homg_point_3d<Type>& operator+=(vgl_homg_point_3d<Type>& p,
00211 vgl_vector_3d<Type> const& v)
00212 {
00213 p.set(p.x()+v.x()*p.w(),p.y()+v.y()*p.w(),p.z()+v.z()*p.w(),p.w()); return p;
00214 }
00215
00216
00217
00218 template <class Type> inline
00219 vgl_homg_point_3d<Type> operator-(vgl_homg_point_3d<Type> const& p,
00220 vgl_vector_3d<Type> const& v)
00221 { return p + (-v); }
00222
00223
00224
00225 template <class Type> inline
00226 vgl_homg_point_3d<Type>& operator-=(vgl_homg_point_3d<Type>& p,
00227 vgl_vector_3d<Type> const& v)
00228 { return p += (-v); }
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250 template <class T>
00251 double cross_ratio(vgl_homg_point_3d<T>const& p1, vgl_homg_point_3d<T>const& p2,
00252 vgl_homg_point_3d<T>const& p3, vgl_homg_point_3d<T>const& p4);
00253
00254
00255
00256 template <class Type>
00257 bool collinear(vgl_homg_point_3d<Type> const& p1,
00258 vgl_homg_point_3d<Type> const& p2,
00259 vgl_homg_point_3d<Type> const& p3);
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269 template <class Type> inline
00270 double ratio(vgl_homg_point_3d<Type> const& p1,
00271 vgl_homg_point_3d<Type> const& p2,
00272 vgl_homg_point_3d<Type> const& p3)
00273 { return (p3-p1)/(p2-p1); }
00274
00275
00276
00277
00278
00279
00280
00281 template <class Type> inline
00282 vgl_homg_point_3d<Type> midpoint(vgl_homg_point_3d<Type> const& p1,
00283 vgl_homg_point_3d<Type> const& p2,
00284 Type f = (Type)0.5)
00285 { return p1 + f*(p2-p1); }
00286
00287
00288
00289
00290
00291
00292
00293 template <class Type> inline
00294 vgl_homg_point_3d<Type> centre(vgl_homg_point_3d<Type> const& p1,
00295 vgl_homg_point_3d<Type> const& p2)
00296 {
00297 return vgl_homg_point_3d<Type>(p1.x()*p2.w() + p2.x()*p1.w() ,
00298 p1.y()*p2.w() + p2.y()*p1.w() ,
00299 p1.z()*p2.w() + p2.z()*p1.w() ,
00300 p1.w()*p2.w()*2 );
00301 }
00302
00303
00304
00305
00306 template <class Type> inline
00307 vgl_homg_point_3d<Type> centre(vcl_vector<vgl_homg_point_3d<Type> > const& v)
00308 {
00309 int n=v.size();
00310 assert(n>0);
00311 Type x = 0, y = 0, z = 0;
00312 for (int i=0; i<n; ++i)
00313 x+=v[i].x()/v[i].w(), y+=v[i].y()/v[i].w(), z+=v[i].z()/v[i].w();
00314 return vgl_homg_point_3d<Type>(x,y,z,(Type)n);
00315 }
00316
00317 #define VGL_HOMG_POINT_3D_INSTANTIATE(T) extern "please include vgl/vgl_homg_point_3d.txx first"
00318
00319 #endif // vgl_homg_point_3d_h_