00001 #ifndef mfpf_pose_h_
00002 #define mfpf_pose_h_
00003
00004
00005
00006
00007
00008
00009 #include <vsl/vsl_binary_io.h>
00010 #include <vcl_iostream.h>
00011 #include <vcl_cstdlib.h>
00012 #include <vcl_cmath.h>
00013 #include <vcl_vector.h>
00014 #include <vgl/vgl_point_2d.h>
00015 #include <vgl/vgl_vector_2d.h>
00016
00017
00018
00019
00020 class mfpf_pose
00021 {
00022
00023 vgl_point_2d<double> p_;
00024
00025
00026 vgl_vector_2d<double> u_;
00027 public:
00028
00029 const vgl_point_2d<double>& p() const { return p_; }
00030
00031
00032 vgl_point_2d<double>& p() { return p_; }
00033
00034
00035 const vgl_vector_2d<double>& u() const { return u_; }
00036
00037
00038 vgl_vector_2d<double> v() const
00039 { return vgl_vector_2d<double>(-u_.y(),u_.x()); }
00040
00041
00042 vgl_vector_2d<double>& u() { return u_; }
00043
00044
00045 mfpf_pose(const vgl_point_2d<double>& p,
00046 const vgl_vector_2d<double>& u) : p_(p),u_(u) {}
00047
00048
00049 mfpf_pose(double px, double py, double ux, double uy)
00050 : p_(px,py),u_(ux,uy) {}
00051
00052
00053 mfpf_pose() : p_(0,0),u_(1,0) {}
00054
00055
00056 double sqr_scale() const { return u_.x()*u_.x()+u_.y()*u_.y(); }
00057
00058
00059 double scale() const
00060 { double s2 = u_.x()*u_.x()+u_.y()*u_.y();
00061 return s2>0.0 ? vcl_sqrt(s2) : 0.0;
00062 }
00063
00064
00065 vgl_point_2d<double> operator()(double x, double y) const
00066 { return vgl_point_2d<double>(p_.x()+x*u_.x()-y*u_.y(),
00067 p_.y()+x*u_.y()+y*u_.x()); }
00068
00069
00070 vgl_point_2d<double> operator()(const vgl_point_2d<double>& q) const
00071 { return vgl_point_2d<double>(p_.x()+q.x()*u_.x()-q.y()*u_.y(),
00072 p_.y()+q.x()*u_.y()+q.y()*u_.x()); }
00073
00074
00075 vgl_point_2d<double> apply_inverse(double x, double y) const
00076 {
00077 double dx=x-p_.x(), dy=y-p_.y(),s2=sqr_scale();
00078 return vgl_point_2d<double>((dx*u_.x()+dy*u_.y())/s2,
00079 (dy*u_.x()-dx*u_.y())/s2);
00080 }
00081
00082
00083 vgl_point_2d<double> apply_inverse(const vgl_point_2d<double>& q) const
00084 {
00085 double dx=q.x()-p_.x(), dy=q.y()-p_.y(),s2=sqr_scale();
00086 return vgl_point_2d<double>((dx*u_.x()+dy*u_.y())/s2,
00087 (dy*u_.x()-dx*u_.y())/s2);
00088 }
00089
00090
00091
00092 mfpf_pose rel_pose(const mfpf_pose& pose) const
00093 {
00094 vgl_point_2d<double> p1 = apply_inverse(pose.p());
00095 vgl_vector_2d<double> u1 = apply_inverse(pose.p()+pose.u())-p1;
00096 return mfpf_pose(p1,u1);
00097 }
00098
00099
00100 mfpf_pose inverse() const
00101 {
00102 vgl_point_2d<double> p1 = apply_inverse(0,0);
00103 double s2=sqr_scale();
00104 vgl_vector_2d<double> u1(u_.x()/s2,-u_.y()/s2);
00105 return mfpf_pose(p1,u1);
00106 }
00107 };
00108
00109 inline bool operator==(const mfpf_pose& p1,
00110 const mfpf_pose& p2)
00111 {
00112 const double tol=1e-6;
00113 return vcl_fabs(p1.p().x()-p2.p().x())<tol &&
00114 vcl_fabs(p1.p().y()-p2.p().y())<tol &&
00115 vcl_fabs(p1.u().x()-p2.u().x())<tol &&
00116 vcl_fabs(p1.u().y()-p2.u().y())<tol;
00117 }
00118
00119 inline bool operator!=(const mfpf_pose& p1,
00120 const mfpf_pose& p2)
00121 { return !(p1==p2); }
00122
00123
00124
00125
00126
00127 inline double mfpf_max_sqr_diff(const mfpf_pose& p1,
00128 const mfpf_pose& p2, double r)
00129 {
00130 double dx = vcl_fabs(p1.p().x()-p2.p().x())
00131 + r*vcl_fabs(p1.u().x()-p2.u().x());
00132 double dy = vcl_fabs(p1.p().y()-p2.p().y())
00133 + r*vcl_fabs(p1.u().y()-p2.u().y());
00134 return dx*dx+dy*dy;
00135 }
00136
00137 inline vcl_ostream& operator<<(vcl_ostream& os,
00138 const mfpf_pose& p)
00139 {
00140 os<<"{("<<p.p().x()<<','<<p.p().y()<<") u:"
00141 <<p.u().x()<<','<<p.u().y()<<")}";
00142 return os;
00143 }
00144
00145
00146
00147 inline mfpf_pose operator*(const mfpf_pose& p1, const mfpf_pose& p2)
00148 {
00149 vgl_point_2d<double> q = p1(p2.p());
00150 return mfpf_pose(q,p1(p2.p()+p2.u())-q);
00151 }
00152
00153 inline void vsl_b_write(vsl_b_ostream& bfs,
00154 const mfpf_pose& p)
00155 {
00156 vsl_b_write(bfs,short(1));
00157 vsl_b_write(bfs,p.p().x());
00158 vsl_b_write(bfs,p.p().y());
00159 vsl_b_write(bfs,p.u().x());
00160 vsl_b_write(bfs,p.u().y());
00161 }
00162
00163 inline void vsl_b_read(vsl_b_istream& bfs, mfpf_pose& p)
00164 {
00165 short version;
00166 vsl_b_read(bfs,version);
00167 double ux,uy;
00168 switch (version)
00169 {
00170 case (1):
00171 vsl_b_read(bfs,p.p().x());
00172 vsl_b_read(bfs,p.p().y());
00173 vsl_b_read(bfs,ux);
00174 vsl_b_read(bfs,uy);
00175 p.u()=vgl_vector_2d<double>(ux,uy);
00176 break;
00177 default:
00178 vcl_cerr << "I/O ERROR: vsl_b_read(bfs,mfpf_pose):\n"
00179 << " Unexpected version number " << version << '\n';
00180 vcl_abort();
00181 }
00182 }
00183
00184
00185 inline void vsl_b_write(vsl_b_ostream& bfs,
00186 const vcl_vector<mfpf_pose>& p)
00187 {
00188 vsl_b_write(bfs,short(1));
00189 vsl_b_write(bfs,unsigned(p.size()));
00190 for (unsigned i=0;i<p.size();++i)
00191 vsl_b_write(bfs,p[i]);
00192 }
00193
00194
00195 inline void vsl_b_read(vsl_b_istream& bfs,
00196 vcl_vector<mfpf_pose>& p)
00197 {
00198 short version;
00199 vsl_b_read(bfs,version);
00200 unsigned n;
00201 switch (version)
00202 {
00203 case (1):
00204 vsl_b_read(bfs,n);
00205 p.resize(n);
00206 for (unsigned i=0;i<n;++i) vsl_b_read(bfs,p[i]);
00207 break;
00208 default:
00209 vcl_cerr << "vsl_b_read(bfs,vcl_vector<mfpf_pose>): "
00210 << "Unexpected version number " << version << vcl_endl;
00211 vcl_abort();
00212 }
00213 }
00214
00215 #endif // mfpf_pose_h_
00216