contrib/brl/bbas/bsol/bsol_intrinsic_curve_3d.h
Go to the documentation of this file.
00001 #ifndef bsol_intrinsic_curve_3d_h_
00002 #define bsol_intrinsic_curve_3d_h_
00003 //*****************************************************************************
00004 //:
00005 // \file
00006 // \brief Generic intrinsic curve in 3D that has intrinsic curvature, torsion, d_theta, d_s defined.
00007 // Note that to make the definition intrinsic, I inherit it from vsol_curve_3d.
00008 //
00009 // \author MingChing Chang
00010 // \date   2004-03-19
00011 //
00012 // \verbatim
00013 //  Modifications
00014 //   2004-03-17 MingChing Chang Creation
00015 // \endverbatim
00016 //*****************************************************************************
00017 
00018 #include <vcl_vector.h>
00019 #include <vcl_iostream.h>
00020 #include <vcl_string.h>
00021 #include <vcl_cassert.h>
00022 #include <vsol/vsol_curve_3d.h>
00023 #include <vsol/vsol_point_3d.h>
00024 #include <vsol/vsol_point_3d_sptr.h>
00025 #include <vgl/vgl_vector_3d.h>
00026 
00027 //: For Pi definition, use pi, and pi_over_2 defined in vnl/vnl_math.h
00028 
00029 #define ZERO_TOLERANCE 1E-1
00030 
00031 //: General 3d intrinsic curve class
00032 
00033 class bsol_intrinsic_curve_3d : public vsol_curve_3d
00034 {
00035  protected:
00036 
00037   //***************************************************************************
00038   // Data members
00039   // Description: List of vsol_point_3d
00040   vcl_vector<vsol_point_3d_sptr> *storage_;
00041   //: First point of the curve : just to conform to vsol_curve_2d standard
00042   vsol_point_3d_sptr p0_;
00043   //: Last point of the curve
00044   vsol_point_3d_sptr p1_;
00045   //: Arclength measured from the p0_
00046   vcl_vector<double> arcLength_;
00047   //: Arclength of the current segment i to i+1
00048   vcl_vector<double> s_;
00049   //: The z angle of the intrinsic curve
00050   vcl_vector<double> phi_;
00051   //: First derivative of the z angle of the intrinsic curve
00052   vcl_vector<double> phis_;
00053   //: Second derivative of the z angle of the intrinsic curve
00054   vcl_vector<double> phiss_;
00055   //: The xy angle of the intrinsic curve
00056   vcl_vector<double> theta_;
00057   //: First derivative of the xy angle of the intrinsic curve
00058   vcl_vector<double> thetas_;
00059   //: Second derivative of the xy angle of the intrinsic curve
00060   vcl_vector<double> thetass_;
00061   //: Curvature of the intrinsic curve
00062   vcl_vector<double> curvature_;
00063   //: Torsion of the intrinsic curve
00064   vcl_vector<double> torsion_;
00065   //: Total curvature of the intrinsic curve
00066   double totalCurvature_;
00067   //: Total angle change of the intrinsic curve
00068   double totalAngleChange_;
00069 
00070   //: Tangent vector for each point
00071   vcl_vector<vgl_vector_3d<double>*> Tangent_;
00072   //: Normal vector for each point
00073   vcl_vector<vgl_vector_3d<double>*> Normal_;
00074   //: Binormal vector for each point
00075   vcl_vector<vgl_vector_3d<double>*> Binormal_;
00076 
00077   //: A flag to indicate if this curve is open or close
00078   bool isOpen_;
00079   //: The '*.con3' filename of this intrinsic curve
00080   vcl_string CON3Filename_;
00081 
00082  public:
00083   //***************************************************************************
00084   // Initialization
00085 
00086   //: Default Constructor
00087   bsol_intrinsic_curve_3d();
00088   //: Constructor from a vcl_vector of points
00089   bsol_intrinsic_curve_3d(const vcl_vector<vsol_point_3d_sptr> &new_vertices);
00090   //: Copy constructor
00091   bsol_intrinsic_curve_3d(const bsol_intrinsic_curve_3d &other);
00092   //: Destructor
00093   virtual ~bsol_intrinsic_curve_3d();
00094   //: Clone `this': creation of a new object and initialization
00095   // See Prototype pattern
00096   virtual vsol_spatial_object_3d* clone(void) const;
00097   //: Return a platform independent string identifying the class
00098   vcl_string is_a() const { return vcl_string("bsol_intrinsic_curve_3d"); }
00099 
00100   //***************************************************************************
00101   // Access
00102 
00103   //: Return the first point of `this';  pure virtual of vsol_curve_3d
00104   virtual vsol_point_3d_sptr p0() const { return p0_; }
00105   //: Return the last point of `this';   pure virtual of vsol_curve_3d
00106   virtual vsol_point_3d_sptr p1() const { return p1_; }
00107   //: Is `i' a valid index for the list of vertices ?
00108   bool valid_index(unsigned int i) const { return i<size(); }
00109   //: Return vertex `i'
00110   vsol_point_3d_sptr vertex(const int i) const {
00111     assert(valid_index(i));
00112     return (*storage_)[i];
00113   }
00114   //: Return x coord of vertex `i'
00115   double x (const int i) const {
00116     assert(valid_index(i));
00117     return (*storage_)[i]->x();
00118   }
00119   //: Return y coord of vertex `i'
00120   double y (const int i) const {
00121     assert(valid_index(i));
00122     return (*storage_)[i]->y();
00123   }
00124   //: Return z coord of vertex `i'
00125   double z (const int i) const {
00126     assert(valid_index(i));
00127     return (*storage_)[i]->z();
00128   }
00129   //: Return the number of vertices
00130   unsigned int size(void) const {
00131     return storage_->size();
00132   }
00133   //: Return the total length of the intrinsic curve
00134   virtual double length (void) const {
00135     return arcLength_[storage_->size()-1];
00136   }
00137   //: Return the total arclength from vertex `0' to vertex `i'
00138   double arcLength (const int i) const {
00139     assert (valid_index(i));
00140     if (i==0)
00141       return arcLength_[1];
00142     else
00143       return arcLength_[i];
00144   }
00145   //: Return the total arclength of the current vertex `i-1' to vertex `i'
00146   double s (const int i) const {
00147     assert (valid_index(i));
00148     if (i==0)
00149       return s_[1];
00150     else
00151       return s_[i];
00152   }
00153   //: Return the normalized arclength from vertex `0' to vertex `i'
00154   double normArcLength (const int i) const {
00155     return arcLength (i) / length();
00156   }
00157   //: Return the dx vertex `i-1' to vertex `i'
00158   double dx (const int i) const {
00159     assert(valid_index(i) && valid_index(i-1));
00160     return (*storage_)[i]->x() - (*storage_)[i-1]->x();
00161   }
00162   //: Return the dy vertex `i-1' to vertex `i'
00163   double dy (const int i) const {
00164     assert(valid_index(i) && valid_index(i-1));
00165     return (*storage_)[i]->y() - (*storage_)[i-1]->y();
00166   }
00167   //: Return the dz vertex `i-1' to vertex `i'
00168   double dz (const int i) const {
00169     assert(valid_index(i));
00170     return (*storage_)[i]->z() - (*storage_)[i-1]->z();
00171   }
00172   //: Return the angle of vertex `i'
00173   double phi (const int i) const {
00174     assert(valid_index(i));
00175     if (i==0)
00176       return phi_[1];
00177     else
00178       return phi_[i];
00179   }
00180   //: Return the angle of vertex `i'
00181   double phis (const int i) const {
00182     assert(valid_index(i));
00183     if (i==0 || i==1) {
00184       if (size()<3)
00185         return 0; //assert (size()>2);
00186       else
00187         return phis_[2];
00188     }
00189     else
00190       return phis_[i];
00191   }
00192   //: Return the angle of vertex `i'
00193   double phiss (const int i) const {
00194     assert(valid_index(i));
00195     if (i==0 || i==1 || i==2) {
00196       if (size()<4)
00197         return 0; //assert (size()>3);
00198       else
00199         return phiss_[3];
00200     }
00201     else
00202       return phiss_[i];
00203   }
00204   //: Return the angle of vertex `i'
00205   double theta (const int i) const {
00206     assert(valid_index(i));
00207     if (i==0)
00208       return theta_[1];
00209     else
00210       return theta_[i];
00211   }
00212   //: Return the angle of vertex `i'
00213   double thetas (const int i) const {
00214     assert(valid_index(i));
00215     if (i==0 || i==1) {
00216       if (size()<3)
00217         return 0; //assert (size()>2);
00218       else
00219         return thetas_[2];
00220     }
00221     else
00222       return thetas_[i];
00223   }
00224   //: Return the angle of vertex `i'
00225   double thetass (const int i) const {
00226     assert(valid_index(i));
00227     if (i==0 || i==1 || i==2) {
00228       if (size()<4)
00229         return 0; //assert (size()>3);
00230       else
00231         return thetass_[3];
00232     }
00233     else
00234       return thetass_[i];
00235   }
00236   //: Return the curvature of vertex `i'
00237   double curvature (const int i) const {
00238     assert(valid_index(i));
00239     if (i==0 || i==1) {
00240       if (size()<3)
00241         return 0; //assert (size()>2);
00242       else
00243         return curvature_[2];
00244     }
00245     else
00246       return curvature_[i];
00247   }
00248   //: Return the curvature of vertex `i'
00249   double torsion (const int i) const {
00250     assert(valid_index(i));
00251     if (i==0 || i==1|| i==2) {
00252       if (size()<4)
00253         return 0; //assert (size()>3);
00254       else
00255         return torsion_[3];
00256     }
00257     return torsion_[i];
00258   }
00259 
00260   //: Return the total curvature of the intrinsic curve
00261   double totalCurvature (void) {
00262     return totalCurvature_;
00263   }
00264   //: Return the total angle change of the intrinsic curve
00265   double totalAngleChange (void) {
00266     return totalAngleChange_;
00267   }
00268   //: Return Tangent vector for the `i-th' vertex
00269   vgl_vector_3d<double>* Tangent(int i) {
00270     assert(valid_index(i));
00271     if (i==0)
00272       return Tangent_[1];
00273     else
00274       return Tangent_[i];
00275   }
00276   //: Return Normal vector for the `i-th' vertex
00277   vgl_vector_3d<double>* Normal(int i) {
00278     assert(valid_index(i));
00279     if (i==0 || i==1) {
00280       if (size()<3)
00281         return 0; //assert (size()>2);
00282       else
00283         return Normal_[2];
00284     }
00285     else
00286       return Normal_[i];
00287   }
00288   //: Return Binormal vector for the `i-th' vertex
00289   vgl_vector_3d<double>* Binormal(int i) {
00290     assert(valid_index(i));
00291     if (i==0 || i==1) {
00292       if (size()<3)
00293         return 0; //assert (size()>2);
00294       else
00295         return Binormal_[2];
00296     }
00297     else
00298       return Binormal_[i];
00299   }
00300 
00301   //: Return if this curve is open or close
00302   bool isOpen (void) {
00303     return isOpen_;
00304   }
00305   //: The '*.con3' filename of this intrinsic curve
00306   vcl_string CON3Filename (void) {
00307     return CON3Filename_;
00308   }
00309 
00310   //***************************************************************************
00311   // Comparison
00312 
00313   //: Has `this' the same points than `other' in the same order ?
00314   virtual bool operator==(const bsol_intrinsic_curve_3d &other) const;
00315   virtual bool operator==(const vsol_spatial_object_3d& obj) const; // virtual of vsol_spatial_object_3d
00316   //: Has `this' the same points than `other' in the same order ?
00317   inline bool operator!=(const bsol_intrinsic_curve_3d &o) const {return !operator==(o);}
00318 
00319  public:
00320 
00321   //***************************************************************************
00322   // Status setting
00323 
00324   //: Set the first point of the curve
00325   virtual void set_p0 (const vsol_point_3d_sptr &new_p0) {
00326     p0_=new_p0;
00327     storage_->push_back(p0_);
00328   }
00329   //: Set the last point of the curve
00330   virtual void set_p1 (const vsol_point_3d_sptr &new_p1) {
00331     p1_=new_p1;
00332     storage_->push_back(p0_);
00333   }
00334   //: Compute intrinsic properties.
00335   // For add_vertex(), remove_vertex(), modify_vertex(), insert_vertex()
00336   // don't forget to call computeProperties()
00337   void computeProperties ();
00338   //void computeProperties_old ();
00339 
00340   //: Delete all points of the intrinsic curve
00341   void clear();
00342 
00343   //: Add another point to the end of the intrinsic curve
00344   void add_vertex (const vsol_point_3d_sptr &new_p) {
00345     storage_->push_back(new_p);
00346   }
00347   //: Add another point to the end of the intrinsic curve
00348   void add_vertex (double x, double y, double z) {
00349     vsol_point_3d_sptr newpoint = new vsol_point_3d (x, y, z);
00350     add_vertex (newpoint);
00351   }
00352   //: Remove one vertex from the intrinsic curve
00353   void remove_vertex (const int i) {
00354     assert (valid_index(i));
00355     storage_->erase (storage_->begin() + i);
00356   }
00357   //: Modify one vertex of the intrinsic curve
00358   void modify_vertex (const int i, double x, double y, double z) {
00359     assert (valid_index(i));
00360     (*storage_)[i]->set_x (x);
00361     (*storage_)[i]->set_y (y);
00362     (*storage_)[i]->set_z (z);
00363   }
00364   //: Insert one vertex to position `i' of the intrinsic curve
00365   //  Note that it inserts the vertex into `i-1'
00366   void insert_vertex (int i, double x, double y, double z) {
00367     assert (valid_index(i));
00368     vsol_point_3d_sptr pt = new vsol_point_3d (x,y,z);
00369     vcl_vector< vsol_point_3d_sptr >::iterator it = storage_->begin();
00370     it += i;
00371     storage_->insert (it, pt);
00372   }
00373 
00374   //: File I/O
00375   bool LoadCON3File (vcl_string fileName);
00376   bool SaveCON3File (vcl_string fileName);
00377 
00378   //***************************************************************************
00379   // Basic operations
00380 
00381   //: Compute the bounding box of `this'
00382   virtual void compute_bounding_box(void) const;
00383 
00384   //: output description to stream
00385   inline void describe(vcl_ostream &strm, int blanking=0) const {
00386     if (blanking < 0) blanking = 0; while (blanking--) strm << ' ';
00387     strm << "<bsol_intrinsic_curve_3d " << ( isOpen_ ? "open" : "closed" )
00388          << ", total curvature=" << totalCurvature_
00389          << ", total angle change=" << totalAngleChange_ << ">\n";
00390   }
00391 };
00392 
00393 #endif // bsol_intrinsic_curve_3d_h_