contrib/gel/vsol/vsol_polyline_3d.cxx
Go to the documentation of this file.
00001 // This is gel/vsol/vsol_polyline_3d.cxx
00002 #include "vsol_polyline_3d.h"
00003 //:
00004 // \file
00005 
00006 #include <vsol/vsol_point_3d.h>
00007 #include <vgl/vgl_vector_3d.h>
00008 #include <vsl/vsl_vector_io.h>
00009 #include <vcl_iostream.h>
00010 #include <vcl_cassert.h>
00011 
00012 //***************************************************************************
00013 // Initialization
00014 //***************************************************************************
00015 
00016 //---------------------------------------------------------------------------
00017 //: Default Constructor
00018 //---------------------------------------------------------------------------
00019 vsol_polyline_3d::vsol_polyline_3d()
00020   : vsol_curve_3d()
00021 {
00022   storage_=new vcl_vector<vsol_point_3d_sptr>();
00023   p0_ = 0;
00024   p1_ = 0;
00025 }
00026 
00027 //---------------------------------------------------------------------------
00028 //: Constructor from a vcl_vector of points
00029 //---------------------------------------------------------------------------
00030 
00031 vsol_polyline_3d::vsol_polyline_3d(vcl_vector<vsol_point_3d_sptr> const& new_vertices)
00032   : vsol_curve_3d()
00033 {
00034   storage_=new vcl_vector<vsol_point_3d_sptr>(new_vertices);
00035   int n = storage_->size();
00036   if (n<2)
00037   {
00038     p0_ = 0;
00039     p1_ = 0;
00040     return;
00041   }
00042   p0_ = (*storage_)[0];
00043   p1_ = (*storage_)[n-1];
00044 }
00045 
00046 //---------------------------------------------------------------------------
00047 // Copy constructor
00048 //---------------------------------------------------------------------------
00049 vsol_polyline_3d::vsol_polyline_3d(vsol_polyline_3d const& other)
00050   : vsol_curve_3d(other)
00051 {
00052   storage_=new vcl_vector<vsol_point_3d_sptr>(*other.storage_);
00053   for (unsigned int i=0;i<storage_->size();++i)
00054     (*storage_)[i]=new vsol_point_3d(*((*other.storage_)[i]));
00055   p0_ = other.p0_;
00056   p1_ = other.p1_;
00057 }
00058 
00059 //---------------------------------------------------------------------------
00060 // Destructor
00061 //---------------------------------------------------------------------------
00062 vsol_polyline_3d::~vsol_polyline_3d()
00063 {
00064   delete storage_;
00065 }
00066 
00067 //---------------------------------------------------------------------------
00068 //: Clone `this': creation of a new object and initialization
00069 // See Prototype pattern
00070 //---------------------------------------------------------------------------
00071 vsol_spatial_object_3d* vsol_polyline_3d::clone() const
00072 {
00073   return new vsol_polyline_3d(*this);
00074 }
00075 
00076 //***************************************************************************
00077 // Access
00078 //***************************************************************************
00079 
00080 //---------------------------------------------------------------------------
00081 //: Return vertex `i'
00082 //  REQUIRE: valid_index(i)
00083 //---------------------------------------------------------------------------
00084 vsol_point_3d_sptr vsol_polyline_3d::vertex(const int i) const
00085 {
00086   // require
00087   assert(valid_index(i));
00088 
00089   return (*storage_)[i];
00090 }
00091 
00092 //***************************************************************************
00093 // Comparison
00094 //***************************************************************************
00095 
00096 //---------------------------------------------------------------------------
00097 //: Has `this' the same points than `other' in the same order ?
00098 //---------------------------------------------------------------------------
00099 bool vsol_polyline_3d::operator==(vsol_polyline_3d const& other) const
00100 {
00101   if (this==&other)
00102     return true;
00103   //check endpoint equality since that is cheaper then checking each vertex
00104   //and if it fails we are done
00105   bool epts_eq = vsol_curve_3d::endpoints_equal(other);
00106   if (!epts_eq)
00107     return false;
00108   //Do the polylines have the same number of vertices?
00109   if (storage_->size()!=other.storage_->size())
00110     return false;
00111   //The easy tests are done.  Now compare each vertex
00112   int n = storage_->size();
00113   for (int i=0; i<n; i++)
00114     if (*((*storage_)[i])!=*((*other.storage_)[i]))
00115       return false;
00116   return true;
00117 }
00118 
00119 //: spatial object equality
00120 
00121 bool vsol_polyline_3d::operator==(vsol_spatial_object_3d const& obj) const
00122 {
00123   return
00124     obj.cast_to_curve() && obj.cast_to_curve()->cast_to_polyline() &&
00125     *this == *obj.cast_to_curve()->cast_to_polyline();
00126 }
00127 
00128 //***************************************************************************
00129 // Status report
00130 //***************************************************************************
00131 
00132 //---------------------------------------------------------------------------
00133 //: Return the length of `this'
00134 //---------------------------------------------------------------------------
00135 double vsol_polyline_3d::length() const
00136 {
00137   double l = 0.0;
00138   for (unsigned int i=0;i+1<storage_->size();++i)
00139     l += ::length(vgl_vector_3d<double>((*storage_)[i+1]->x(),(*storage_)[i+1]->y(),(*storage_)[i+1]->z())
00140                  -vgl_vector_3d<double>((*storage_)[i]->x(),(*storage_)[i]->y(),(*storage_)[i]->z()));
00141   return l;
00142 }
00143 
00144 //---------------------------------------------------------------------------
00145 //: Compute the bounding box of `this'
00146 //---------------------------------------------------------------------------
00147 void vsol_polyline_3d::compute_bounding_box() const
00148 {
00149   set_bounding_box((*storage_)[0]->x(), (*storage_)[0]->y(), (*storage_)[0]->z());
00150   for (unsigned int i=1;i<storage_->size();++i)
00151     add_to_bounding_box((*storage_)[i]->x(), (*storage_)[i]->y(), (*storage_)[i]->z());
00152 }
00153 
00154 //***************************************************************************
00155 // Status setting
00156 //***************************************************************************
00157 
00158 //---------------------------------------------------------------------------
00159 //: Set the first point of the curve
00160 // Require: in(new_p0)
00161 //---------------------------------------------------------------------------
00162 void vsol_polyline_3d::set_p0(vsol_point_3d_sptr const& new_p0)
00163 {
00164   p0_=new_p0;
00165   storage_->push_back(p0_);
00166 }
00167 
00168 //---------------------------------------------------------------------------
00169 //: Set the last point of the curve
00170 // Require: in(new_p1)
00171 //---------------------------------------------------------------------------
00172 void vsol_polyline_3d::set_p1(vsol_point_3d_sptr const& new_p1)
00173 {
00174   p1_=new_p1;
00175   storage_->push_back(p0_);
00176 }
00177 
00178 //---------------------------------------------------------------------------
00179 //: Add another point to the curve
00180 //---------------------------------------------------------------------------
00181 void vsol_polyline_3d::add_vertex(vsol_point_3d_sptr const& new_p)
00182 {
00183   storage_->push_back(new_p);
00184 }
00185 
00186 //----------------------------------------------------------------
00187 // ================   Binary I/O Methods ========================
00188 //----------------------------------------------------------------
00189 
00190 //: Binary save self to stream.
00191 void vsol_polyline_3d::b_write(vsl_b_ostream &os) const
00192 {
00193   if (!storage_)
00194     vsl_b_write(os, false); // Indicate null pointer stored
00195   else
00196   {
00197     vsl_b_write(os, true); // Indicate non-null pointer stored
00198     vsl_b_write(os, version());
00199     vsl_b_write(os, *storage_);
00200   }
00201 }
00202 //: Binary load self from stream (not typically used)
00203 void vsol_polyline_3d::b_read(vsl_b_istream &is)
00204 {
00205   if (!is)
00206     return;
00207   delete storage_;
00208   storage_ = new vcl_vector<vsol_point_3d_sptr>();
00209   p0_=0;
00210   p1_=0;
00211   bool null_ptr;
00212   vsl_b_read(is, null_ptr);
00213   if (!null_ptr)
00214     return;
00215   short ver;
00216   vsl_b_read(is, ver);
00217   switch (ver)
00218   {
00219    case 1: {
00220     vsl_b_read(is, *storage_);
00221     int n = storage_->size();
00222     if (n<2)
00223       break;
00224     p0_=(*storage_)[0];
00225     p1_=(*storage_)[n-1];
00226     break;
00227    }
00228    default:
00229     vcl_cerr << "vsol_polyline_3d: unknown I/O version " << ver << '\n';
00230   }
00231 }
00232 //: Return IO version number;
00233 short vsol_polyline_3d::version() const
00234 {
00235   return 1;
00236 }
00237 
00238 //: Print an ascii summary to the stream
00239 void vsol_polyline_3d::print_summary(vcl_ostream &os) const
00240 {
00241   os << *this;
00242 }
00243 
00244 //: Binary save vsol_polyline_3d to stream.
00245 void
00246 vsl_b_write(vsl_b_ostream &os, const vsol_polyline_3d* p)
00247 {
00248   if (p==0) {
00249     vsl_b_write(os, false); // Indicate null pointer stored
00250   }
00251   else {
00252     vsl_b_write(os,true); // Indicate non-null pointer stored
00253     p->b_write(os);
00254   }
00255 }
00256 
00257 
00258 //: Binary load vsol_polyline_3d from stream.
00259 void
00260 vsl_b_read(vsl_b_istream &is, vsol_polyline_3d* &p)
00261 {
00262   delete p;
00263   bool not_null_ptr;
00264   vsl_b_read(is, not_null_ptr);
00265   if (not_null_ptr) {
00266     p = new vsol_polyline_3d();
00267     p->b_read(is);
00268   }
00269   else
00270     p = 0;
00271 }
00272 
00273 void vsol_polyline_3d::describe(vcl_ostream &strm, int blanking) const
00274 {
00275   if (blanking < 0) blanking = 0; while (blanking--) strm << ' ';
00276   strm << "[vsol_polyline_3d";
00277   for (unsigned int i=0; i<size(); ++i)
00278     strm << ' ' << *(vertex(i));
00279   strm << ']' << vcl_endl;
00280 }