contrib/gel/vsol/vsol_rectangle_2d.cxx
Go to the documentation of this file.
00001 // This is gel/vsol/vsol_rectangle_2d.cxx
00002 #include "vsol_rectangle_2d.h"
00003 //:
00004 // \file
00005 #include <vcl_cassert.h>
00006 #include <vnl/vnl_math.h>
00007 #include <vcl_cmath.h> // for fabs()
00008 #include <vcl_iostream.h>
00009 #include <vgl/vgl_vector_2d.h>
00010 #include <vsol/vsol_point_2d.h>
00011 #include <vbl/io/vbl_io_smart_ptr.h>
00012 
00013 //***************************************************************************
00014 // Initialization
00015 //***************************************************************************
00016 
00017 //---------------------------------------------------------------------------
00018 //: Default Constructor - needed for binary I/O
00019 //---------------------------------------------------------------------------
00020 vsol_rectangle_2d::vsol_rectangle_2d()
00021  : vsol_polygon_2d()
00022 {
00023   storage_->clear();
00024   storage_->push_back(new vsol_point_2d(0.0,0.0));
00025   storage_->push_back(new vsol_point_2d(0.0,1.0));
00026   storage_->push_back(new vsol_point_2d(1.0,1.0));
00027   storage_->push_back(new vsol_point_2d(1.0,0.0));
00028 }
00029 
00030 //---------------------------------------------------------------------------
00031 //: Constructor from 4 points, the corners of the rectangle
00032 //---------------------------------------------------------------------------
00033 vsol_rectangle_2d::vsol_rectangle_2d(const vsol_point_2d_sptr &new_p0,
00034                                      const vsol_point_2d_sptr &new_p1,
00035                                      const vsol_point_2d_sptr &new_p2,
00036                                      const vsol_point_2d_sptr &new_p3)
00037  : vsol_polygon_2d()
00038 {
00039   storage_->clear();
00040   storage_->push_back(new_p0);
00041   storage_->push_back(new_p1);
00042   storage_->push_back(new_p2);
00043   storage_->push_back(new_p3);
00044 }
00045 
00046 //---------------------------------------------------------------------------
00047 //: Constructor from 3 points.
00048 // Description: `new_pc' is the origin of the rectangle. `new_pabs' defines
00049 //              the abscissa axis and the width/2. `new_pord' defines the
00050 //              ordinate axis and the height/2.
00051 // Require: valid_vertices(new_pc,new_pabs,new_pord)
00052 //---------------------------------------------------------------------------
00053 vsol_rectangle_2d::vsol_rectangle_2d(const vsol_point_2d_sptr &new_pc,
00054                                      const vsol_point_2d_sptr &new_pabs,
00055                                      const vsol_point_2d_sptr &new_pord)
00056  : vsol_polygon_2d()
00057 {
00058   vgl_vector_2d<double> a(new_pabs->x(), new_pabs->y());
00059   vgl_vector_2d<double> o(new_pord->x(), new_pord->y());
00060   vgl_vector_2d<double> c(new_pc->x(), new_pc->y());
00061   // require
00062   assert(vcl_fabs(dot_product(a,o))<1e-06);
00063   vgl_vector_2d<double> v0 = c-a-o;
00064   vgl_vector_2d<double> v1 = c+a-o;
00065   vgl_vector_2d<double> v2 = c+a+o;
00066   vgl_vector_2d<double> v3 = c-a+o;
00067 
00068   storage_->clear();
00069   storage_->push_back(new vsol_point_2d(v0.x(), v0.y()));
00070   storage_->push_back(new vsol_point_2d(v1.x(), v1.y()));
00071   storage_->push_back(new vsol_point_2d(v2.x(), v2.y()));
00072   storage_->push_back(new vsol_point_2d(v3.x(), v3.y()));
00073 }
00074 //---------------------------------------------------------------------------
00075 //: Constructor from center, half_width, half_height, angle(ccw from x axis, in deg/rad)
00076 //---------------------------------------------------------------------------
00077 vsol_rectangle_2d::vsol_rectangle_2d(const vsol_point_2d_sptr &center,
00078                                      const double half_width,
00079                                      const double half_height,
00080                                      const double angle,
00081                                      const bool deg)
00082  : vsol_polygon_2d()
00083 {
00084   assert(half_width>0&&half_height>0);
00085   double ang = angle;
00086   if (deg)
00087     ang = vnl_math::pi_over_180*angle;
00088   double c = vcl_cos(ang), s = vcl_sin(ang);
00089   vgl_vector_2d<double> a(half_width*c, half_width*s);
00090   vgl_vector_2d<double> b(-half_height*s, half_height*c);
00091   vgl_vector_2d<double> v0 = -a-b;
00092   vgl_vector_2d<double> v1 = a-b;
00093   vgl_vector_2d<double> v2 = a+b;
00094   vgl_vector_2d<double> v3 = -a+b;
00095   storage_->clear();
00096   storage_->push_back(center->plus_vector(v0));
00097   storage_->push_back(center->plus_vector(v1));
00098   storage_->push_back(center->plus_vector(v2));
00099   storage_->push_back(center->plus_vector(v3));
00100 }
00101 
00102 //---------------------------------------------------------------------------
00103 // Copy constructor
00104 //---------------------------------------------------------------------------
00105 vsol_rectangle_2d::vsol_rectangle_2d(const vsol_rectangle_2d &other)
00106   : vsol_polygon_2d(other)
00107 {
00108 }
00109 
00110 //---------------------------------------------------------------------------
00111 // Destructor
00112 //---------------------------------------------------------------------------
00113 vsol_rectangle_2d::~vsol_rectangle_2d()
00114 {
00115 }
00116 
00117 //---------------------------------------------------------------------------
00118 //: Clone `this': creation of a new object and initialization
00119 // See Prototype pattern
00120 //---------------------------------------------------------------------------
00121 vsol_spatial_object_2d* vsol_rectangle_2d::clone(void) const
00122 {
00123   return new vsol_rectangle_2d(*this);
00124 }
00125 
00126 //***************************************************************************
00127 // Access
00128 //***************************************************************************
00129 
00130 //---------------------------------------------------------------------------
00131 //: Return the first vertex
00132 //---------------------------------------------------------------------------
00133 vsol_point_2d_sptr vsol_rectangle_2d::p0(void) const
00134 {
00135   return (*storage_)[0];
00136 }
00137 
00138 //---------------------------------------------------------------------------
00139 //: Return the second vertex
00140 //---------------------------------------------------------------------------
00141 vsol_point_2d_sptr vsol_rectangle_2d::p1(void) const
00142 {
00143   return (*storage_)[1];
00144 }
00145 
00146 //---------------------------------------------------------------------------
00147 //: Return the third vertex
00148 //---------------------------------------------------------------------------
00149 vsol_point_2d_sptr vsol_rectangle_2d::p2(void) const
00150 {
00151   return (*storage_)[2];
00152 }
00153 
00154 //---------------------------------------------------------------------------
00155 //: Return the last vertex
00156 //---------------------------------------------------------------------------
00157 vsol_point_2d_sptr vsol_rectangle_2d::p3(void) const
00158 {
00159   return (*storage_)[3];
00160 }
00161 
00162 //***************************************************************************
00163 // Comparison
00164 //***************************************************************************
00165 
00166 //---------------------------------------------------------------------------
00167 //: Has `this' the same points than `other' in the same order ?
00168 //---------------------------------------------------------------------------
00169 bool vsol_rectangle_2d::operator==(const vsol_rectangle_2d &other) const
00170 {
00171   return vsol_polygon_2d::operator==(other);
00172 }
00173 
00174 bool vsol_rectangle_2d::operator==(const vsol_polygon_2d &other) const
00175 {
00176   return vsol_polygon_2d::operator==(other);
00177 }
00178 
00179 //: spatial object equality
00180 
00181 bool vsol_rectangle_2d::operator==(const vsol_spatial_object_2d& obj) const
00182 {
00183   return
00184     obj.cast_to_region() && obj.cast_to_region()->cast_to_polygon() &&
00185     *this == *obj.cast_to_region()->cast_to_polygon();
00186 }
00187 
00188 //***************************************************************************
00189 // Status report
00190 //***************************************************************************
00191 
00192 //---------------------------------------------------------------------------
00193 //: Return the width
00194 //---------------------------------------------------------------------------
00195 double vsol_rectangle_2d::width(void) const
00196 {
00197   return (*storage_)[0]->distance((*storage_)[1]);
00198 }
00199 
00200 //---------------------------------------------------------------------------
00201 //: Return the height
00202 //---------------------------------------------------------------------------
00203 double vsol_rectangle_2d::height(void) const
00204 {
00205   return (*storage_)[1]->distance((*storage_)[2]);
00206 }
00207 
00208 //---------------------------------------------------------------------------
00209 //: Return the area of `this'
00210 //---------------------------------------------------------------------------
00211 double vsol_rectangle_2d::area(void) const
00212 {
00213   double result;
00214   result=width()*height();
00215   return result;
00216 }
00217 
00218 //---------------------------------------------------------------------------
00219 //: Are `new_vertices' valid to build a rectangle ?
00220 //---------------------------------------------------------------------------
00221 bool vsol_rectangle_2d::valid_vertices(const vcl_vector<vsol_point_2d_sptr> new_vertices) const
00222 {
00223   if (new_vertices.size() != 3) return false;
00224   vgl_vector_2d<double> a=new_vertices[0]->to_vector(*(new_vertices[1]));
00225   vgl_vector_2d<double> b=new_vertices[1]->to_vector(*(new_vertices[2]));
00226   // the two vectors should be orthogonal:
00227   return dot_product(a,b)==0;
00228 }
00229 
00230 
00231 //----------------------------------------------------------------
00232 // ================   Binary I/O Methods ========================
00233 //----------------------------------------------------------------
00234 
00235 //: Binary save self to stream.
00236 void vsol_rectangle_2d::b_write(vsl_b_ostream &os) const
00237 {
00238   vsl_b_write(os, version());
00239   vsol_polygon_2d::b_write(os);
00240 }
00241 
00242 //: Binary load self from stream (not typically used)
00243 void vsol_rectangle_2d::b_read(vsl_b_istream &is)
00244 {
00245   if (!is)
00246     return;
00247   short ver;
00248   vsl_b_read(is, ver);
00249   switch (ver)
00250   {
00251    case 1:
00252     vsol_polygon_2d::b_read(is);
00253     if (storage_->size()!=4) {
00254       vcl_cerr << "I/O ERROR: vsol_rectangle_2d::b_read(vsl_b_istream&)\n"
00255                << "           Incorrect number of vertices: "<< storage_->size() << '\n';
00256       is.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00257       return;
00258     }
00259     break;
00260 
00261    default:
00262     vcl_cerr << "I/O ERROR: vsol_rectangle_2d::b_read(vsl_b_istream&)\n"
00263              << "           Unknown version number "<< ver << '\n';
00264     is.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00265     return;
00266   }
00267 }
00268 //: Return IO version number;
00269 short vsol_rectangle_2d::version() const
00270 {
00271   return 1;
00272 }
00273 
00274 //: Print an ascii summary to the stream
00275 void vsol_rectangle_2d::print_summary(vcl_ostream &os) const
00276 {
00277   os << *this;
00278 }
00279 
00280 //external functions
00281 
00282 //: Binary save vsol_rectangle_2d* to stream.
00283 void
00284 vsl_b_write(vsl_b_ostream &os, const vsol_rectangle_2d* r)
00285 {
00286   if (!r) {
00287     vsl_b_write(os, false); // Indicate null rectangle stored
00288   }
00289   else {
00290     vsl_b_write(os,true); // Indicate non-null rectangle stored
00291     r->b_write(os);
00292   }
00293 }
00294 
00295 //: Binary load vsol_rectangle_2d* from stream.
00296 void
00297 vsl_b_read(vsl_b_istream &is, vsol_rectangle_2d* &r)
00298 {
00299   delete r;
00300   bool not_null_ptr;
00301   vsl_b_read(is, not_null_ptr);
00302   if (not_null_ptr) {
00303     r = new vsol_rectangle_2d();
00304     r->b_read(is);
00305   }
00306   else
00307     r = 0;
00308 }
00309 
00310 inline void vsol_rectangle_2d::describe(vcl_ostream &strm, int blanking) const
00311 {
00312   if (blanking < 0) blanking = 0; while (blanking--) strm << ' ';
00313   strm << "<vsol_rectangle_2d with corners";
00314   for (unsigned int i=0; i<size(); ++i)
00315     strm << ' ' << *(vertex(i));
00316   strm << '>' << vcl_endl;
00317 }