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