00001 #include "msm_points.h"
00002
00003
00004
00005
00006
00007 #include <vcl_iostream.h>
00008 #include <vsl/vsl_indent.h>
00009 #include <vsl/vsl_binary_io.h>
00010 #include <vnl/io/vnl_io_vector.h>
00011 #include <vgl/vgl_point_2d.h>
00012 #include <vcl_cstdlib.h>
00013
00014
00015
00016
00017
00018
00019 msm_points::msm_points()
00020 {
00021 }
00022
00023 msm_points::msm_points(unsigned n)
00024 {
00025 v_.set_size(n*2); v_.fill(0.0);
00026 }
00027
00028
00029
00030
00031
00032 msm_points::~msm_points()
00033 {
00034 }
00035
00036
00037 void msm_points::set_size(unsigned n, double x, double y)
00038 {
00039 if (n==size()) return;
00040 v_.set_size(n*2);
00041 double* v=v_.data_block();
00042 double* v_end=v+2*n;
00043 for (;v!=v_end;v+=2)
00044 {
00045 v[0]=x; v[1]=y;
00046 }
00047 }
00048
00049
00050 void msm_points::set_points(const vcl_vector<vgl_point_2d<double> >& pts)
00051 {
00052 unsigned n=pts.size();
00053 v_.set_size(2*n);
00054 double* v=v_.data_block();
00055 vcl_vector<vgl_point_2d<double> >::const_iterator p = pts.begin();
00056 for (;p!=pts.end();v+=2,++p)
00057 {
00058 v[0] = p->x();
00059 v[1] = p->y();
00060 }
00061 }
00062
00063
00064 void msm_points::get_points(vcl_vector<vgl_point_2d<double> >& pts) const
00065 {
00066 pts.resize(size());
00067 const double* v=v_.data_block();
00068 vcl_vector<vgl_point_2d<double> >::iterator p = pts.begin();
00069 for (;p!=pts.end();v+=2,++p)
00070 {
00071 p->x()=v[0];
00072 p->y()=v[1];
00073 }
00074 }
00075
00076
00077 vgl_point_2d<double> msm_points::cog() const
00078 {
00079 const double* v=v_.data_block();
00080 unsigned n=size();
00081 const double* end_v=v+2*n;
00082 double cx=0.0,cy=0.0;
00083 for (;v!=end_v;v+=2) { cx+=v[0]; cy+=v[1]; }
00084 if (n>0) { cx/=n; cy/=n; }
00085 return vgl_point_2d<double>(cx,cy);
00086 }
00087
00088
00089 double msm_points::scale() const
00090 {
00091 vgl_point_2d<double> c;
00092 double s;
00093 get_cog_and_scale(c,s);
00094 return s;
00095 }
00096
00097
00098 void msm_points::get_cog_and_scale(vgl_point_2d<double>& cog, double& scale) const
00099 {
00100 unsigned n=size();
00101 if (n==0) { cog=vgl_point_2d<double>(0,0); scale=0; return; }
00102
00103 const double* v=v_.data_block();
00104 const double* end_v=v+2*n;
00105
00106
00107 double sx=0.0,s2x=0.0,sy=0.0,s2y=0.0;
00108 for (;v!=end_v;v+=2)
00109 {
00110 sx+=v[0]; s2x+=v[0]*v[0];
00111 sy+=v[1]; s2y+=v[1]*v[1];
00112 }
00113
00114 double cx=sx/n, cy=sy/n;
00115 double L2=(s2x+s2y)/n-cx*cx-cy*cy;
00116 scale = 0.0;
00117 if (L2>0) scale=vcl_sqrt(L2);
00118 cog=vgl_point_2d<double>(cx,cy);
00119 }
00120
00121
00122 void msm_points::scale_by(double s)
00123 {
00124 if (s==1.0) return;
00125 v_*=s;
00126 }
00127
00128
00129 void msm_points::translate_by(double tx, double ty)
00130 {
00131 if (tx==0.0 && ty==0.0) return;
00132 double* v=v_.data_block();
00133 double* end_v=v+2*size();
00134 for (;v!=end_v;v+=2)
00135 {
00136 v[0]+=tx;
00137 v[1]+=ty;
00138 }
00139 }
00140
00141
00142 void msm_points::transform_by(double a, double b, double tx, double ty)
00143 {
00144 double* v=v_.data_block();
00145 double* end_v=v+2*size();
00146 for (;v!=end_v;v+=2)
00147 {
00148 double x=v[0],y=v[1];
00149 v[0]=a*x-b*y+tx;
00150 v[1]=b*x+a*y+ty;
00151 }
00152 }
00153
00154
00155 void msm_points::transform_by(const vimt_transform_2d& t)
00156 {
00157 double* v=v_.data_block();
00158 double* end_v=v+2*size();
00159 for (;v!=end_v;v+=2)
00160 {
00161 vgl_point_2d<double> p = t(v[0],v[1]);
00162 v[0]=p.x(); v[1]=p.y();
00163 }
00164 }
00165
00166
00167 void msm_points::get_bounds(vgl_point_2d<double>& b_lo,
00168 vgl_point_2d<double>& b_hi) const
00169 {
00170 if (size()==0)
00171 {
00172 b_lo=vgl_point_2d<double>(0,0);
00173 b_hi=vgl_point_2d<double>(0,0);
00174 return;
00175 }
00176
00177 const double* v=v_.data_block();
00178 const double* end_v=v+2*size();
00179 b_lo=vgl_point_2d<double>(v[0],v[1]);
00180 b_hi=b_lo;
00181 for (;v!=end_v;v+=2)
00182 {
00183 if (v[0]<b_lo.x()) b_lo.x()=v[0];
00184 if (v[0]>b_hi.x()) b_hi.x()=v[0];
00185 if (v[1]<b_lo.y()) b_lo.y()=v[1];
00186 if (v[1]>b_hi.y()) b_hi.y()=v[1];
00187 }
00188 }
00189
00190
00191 vgl_box_2d<double> msm_points::bounds() const
00192 {
00193 vgl_point_2d<double> blo,bhi;
00194 get_bounds(blo,bhi);
00195 return vgl_box_2d<double>(blo,bhi);
00196 }
00197
00198
00199 bool msm_points::operator==(const msm_points& points) const
00200 {
00201 if (points.v_.size()!=v_.size()) return false;
00202 if (size()==0) return true;
00203 double ssd=vnl_vector_ssd(points.v_,v_);
00204 return (vcl_fabs(ssd/size())<1e-3);
00205 }
00206
00207
00208
00209
00210
00211
00212 bool msm_points::write_text_file(const vcl_string& path) const
00213 {
00214 vcl_ofstream afs(path.c_str(),vcl_ios_out);
00215 if (!afs) return false;
00216
00217 unsigned n = size();
00218 const double* v = v_.data_block();
00219 afs << "version: 1\nn_points: " << n << "\n{" << '\n';
00220 for (unsigned i=0;i<n;++i)
00221 {
00222
00223 afs << v[2*i] << ' ' << v[2*i+1] << '\n';
00224 }
00225 afs << '}' << '\n';
00226
00227 afs.close();
00228
00229 return true;
00230 }
00231
00232 static bool read_points(vcl_istream& afs,
00233 vnl_vector<double>& vec, unsigned n)
00234 {
00235 if (n>999999)
00236 {
00237 vcl_cerr << "msm_points read_points() :\n"
00238 << "Bizarre number of points specified : " << n << vcl_endl;
00239 return false;
00240 }
00241
00242 vec.set_size(2*n);
00243 double* v = vec.data_block();
00244 for (unsigned i=0;i<n;i++,v+=2)
00245 {
00246 if (afs.eof())
00247 {
00248 vcl_cerr << "msm_points read_points() :\n"
00249 << "EOF reached after reading "
00250 << i << " of " << n << " points.\n";
00251 return false;
00252 }
00253 afs>>v[0]>>v[1];
00254 }
00255
00256 return true;
00257 }
00258
00259
00260
00261 bool msm_points::read_text_file(const vcl_string& path)
00262 {
00263 vcl_ifstream afs( path.c_str(), vcl_ios_in );
00264 if (!afs) return false;
00265
00266 vnl_vector<double> vec;
00267 vcl_string label;
00268 afs >> label;
00269 if (label != "version:")
00270 {
00271
00272 int n = vcl_atoi(label.c_str());
00273 if (n>0)
00274 {
00275 return read_points(afs, v_, n);
00276 }
00277
00278 vcl_cerr << "Expecting <version:> got <" << label << vcl_endl;
00279 return false;
00280 }
00281
00282 int ver;
00283 afs >> ver;
00284 if (ver!=1)
00285 {
00286 vcl_cerr << "msm_points::read_text_file() :\n"
00287 << "Cannot cope with version number " << ver << vcl_endl;
00288 return false;
00289 }
00290
00291
00292 int image_nx, image_ny, image_nz;
00293 int n = -1;
00294
00295 afs >> label;
00296 while (!afs.eof() && label != "}")
00297 {
00298 if (label.size()>=2 && label[0]=='/' && label[1]=='/')
00299 {
00300
00301 char buf[256];
00302 afs.get(buf,256);
00303 }
00304 else
00305 if (label=="image_size_x:")
00306 afs>>image_nx;
00307 else if (label=="image_size_y:")
00308 afs>>image_ny;
00309 else if (label=="image_size_z:")
00310 afs>>image_nz;
00311 else if (label=="n_points:")
00312 afs>>n;
00313 else if (label=="{")
00314 {
00315 if (!read_points(afs, v_, n))
00316 return false;
00317 }
00318 else
00319 {
00320 vcl_cerr << "Unexpected label: <" << label << vcl_endl;
00321 return false;
00322 }
00323
00324 afs>>label;
00325 }
00326
00327 return true;
00328 }
00329
00330
00331
00332
00333
00334
00335 short msm_points::version_no() const
00336 {
00337 return 1;
00338 }
00339
00340
00341
00342
00343
00344 vcl_string msm_points::is_a() const
00345 {
00346 return vcl_string("msm_points");
00347 }
00348
00349
00350
00351
00352
00353
00354 void msm_points::print_summary(vcl_ostream& os) const
00355 {
00356 os << size() << " pts: ";
00357 for (unsigned i=0;i<size();++i)
00358 os << '(' << v_[2*i] << ',' << v_[2*i+1] << ')';
00359 }
00360
00361
00362
00363
00364
00365
00366 void msm_points::b_write(vsl_b_ostream& bfs) const
00367 {
00368 vsl_b_write(bfs,version_no());
00369 vsl_b_write(bfs,v_);
00370 }
00371
00372
00373
00374
00375
00376
00377 void msm_points::b_read(vsl_b_istream& bfs)
00378 {
00379 short version;
00380 vsl_b_read(bfs,version);
00381 switch (version)
00382 {
00383 case (1):
00384 vsl_b_read(bfs,v_);
00385 break;
00386 default:
00387 vcl_cerr << "msm_points::b_read() :\n"
00388 << "Unexpected version number " << version << vcl_endl;
00389 vcl_abort();
00390 }
00391 }
00392
00393
00394
00395
00396
00397
00398 void vsl_b_write(vsl_b_ostream& bfs, const msm_points& b)
00399 {
00400 b.b_write(bfs);
00401 }
00402
00403
00404
00405
00406
00407 void vsl_b_read(vsl_b_istream& bfs, msm_points& b)
00408 {
00409 b.b_read(bfs);
00410 }
00411
00412
00413
00414
00415
00416 vcl_ostream& operator<<(vcl_ostream& os,const msm_points& b)
00417 {
00418 os << b.is_a() << ": ";
00419 vsl_indent_inc(os);
00420 b.print_summary(os);
00421 vsl_indent_dec(os);
00422 return os;
00423 }
00424
00425
00426 void vsl_print_summary(vcl_ostream& os,const msm_points& b)
00427 {
00428 os << b;
00429 }