contrib/gel/vdgl/vdgl_digital_curve.cxx
Go to the documentation of this file.
00001 // This is gel/vdgl/vdgl_digital_curve.cxx
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005 //:
00006 // \file
00007 #include "vdgl_digital_curve.h"
00008 #include <vcl_cassert.h>
00009 #include <vbl/io/vbl_io_smart_ptr.h>
00010 #include <vsol/vsol_point_2d.h>
00011 #include <vdgl/vdgl_edgel_chain.h>
00012 #include <vdgl/vdgl_interpolator.h>
00013 #include <vdgl/vdgl_interpolator_linear.h>
00014 #include <vdgl/vdgl_interpolator_cubic.h>
00015 
00016 vdgl_digital_curve::vdgl_digital_curve()
00017   : interpolator_(new vdgl_interpolator_linear(new vdgl_edgel_chain))
00018 {
00019   // This object must have an interpolator, even if it is useless
00020   assert(interpolator_);
00021 }
00022 
00023 vdgl_digital_curve::vdgl_digital_curve( vdgl_interpolator_sptr interpolator)
00024   : interpolator_(interpolator)
00025 {
00026   assert(interpolator);
00027 }
00028 
00029 vdgl_digital_curve::vdgl_digital_curve(vsol_point_2d_sptr const& p0,
00030                                        vsol_point_2d_sptr const& p1)
00031 {
00032   if (!p0||!p1)
00033   {
00034     vdgl_edgel_chain_sptr ec = new vdgl_edgel_chain();
00035     interpolator_ = new vdgl_interpolator_linear(ec);
00036     return;
00037   }
00038   vdgl_edgel_chain* ec = new vdgl_edgel_chain(p0->x(), p0->y(),
00039                                               p1->x(), p1->y());
00040   interpolator_ = new vdgl_interpolator_linear(ec);
00041 }
00042 
00043 vsol_spatial_object_2d* vdgl_digital_curve::clone() const
00044 {
00045   return new vdgl_digital_curve(interpolator_);
00046 }
00047 
00048 short vdgl_digital_curve::order() const
00049 {
00050   return interpolator_->order();
00051 }
00052 
00053 double vdgl_digital_curve::get_x( const double s) const
00054 {
00055   int i= interpolator_->get_edgel_chain()->size() - 1;
00056   double index= (s<0) ? 0.0 : (s>=1) ? i : s*i;
00057 
00058   return interpolator_->get_x(index);
00059 }
00060 
00061 double vdgl_digital_curve::get_y( const double s) const
00062 {
00063   int i= interpolator_->get_edgel_chain()->size() - 1;
00064   double index= (s<0) ? 0.0 : (s>=1) ? i : s*i;
00065 
00066   return interpolator_->get_y(index);
00067 }
00068 
00069 double vdgl_digital_curve::get_grad( const double s) const
00070 {
00071   int i= interpolator_->get_edgel_chain()->size() - 1;
00072   double index= (s<0) ? 0.0 : (s>=1) ? i : s*i;
00073 
00074   return interpolator_->get_grad(index);
00075 }
00076 
00077 double vdgl_digital_curve::get_theta( const double s) const
00078 {
00079   int i= interpolator_->get_edgel_chain()->size() - 1;
00080   double index= (s<0) ? 0.0 : (s>=1) ? i : s*i;
00081 
00082   return interpolator_->get_theta(index);
00083 }
00084 
00085 double vdgl_digital_curve::get_tangent_angle(const double s) const
00086 {
00087   int i= interpolator_->get_edgel_chain()->size() - 1;
00088   double index= (s<0) ? 0.0 : (s>=1) ? i : s*i;
00089   return interpolator_->get_tangent_angle(index);
00090 }
00091 
00092 int vdgl_digital_curve::n_pts() const
00093 {
00094   return interpolator_->get_edgel_chain()->size();
00095 }
00096 
00097 vsol_point_2d_sptr vdgl_digital_curve::p0() const
00098 {
00099   vdgl_edgel_chain_sptr ec = interpolator_->get_edgel_chain();
00100   return new vsol_point_2d(ec->edgel(0).get_pt());
00101 #if 0 // Note that the following will fail for a cubic interpolator!
00102   return new vsol_point_2d(get_x(0), get_y(0));
00103 #endif // 0
00104 }
00105 
00106 vsol_point_2d_sptr vdgl_digital_curve::p1() const
00107 {
00108   vdgl_edgel_chain_sptr ec = interpolator_->get_edgel_chain();
00109   return new vsol_point_2d(ec->edgel(ec->size()-1).get_pt());
00110 #if 0 // Note that the following will fail for a cubic interpolator!
00111   return new vsol_point_2d(get_x(1), get_y(1));
00112 #endif // 0
00113 }
00114 
00115 double vdgl_digital_curve::length() const
00116 {
00117   return interpolator_->get_length();
00118 }
00119 
00120 void vdgl_digital_curve::set_p0(const vsol_point_2d_sptr &p)
00121 {
00122   vcl_cerr << "vdgl_digital_curve::set_p0() not allowed and ignored...\n";
00123   int i = 0;
00124   interpolator_->get_edgel_chain()->set_edgel(i, vdgl_edgel ( p->x(), p->y() ) );
00125 }
00126 
00127 void vdgl_digital_curve::set_p1(const vsol_point_2d_sptr &p )
00128 {
00129   vcl_cerr << "vdgl_digital_curve::set_p1() not allowed and ignored...\n";
00130   int i = interpolator_->get_edgel_chain()->size() - 1;
00131   interpolator_->get_edgel_chain()->set_edgel(i, vdgl_edgel ( p->x(), p->y() ) );
00132 }
00133 
00134 bool vdgl_digital_curve::split(vsol_point_2d_sptr const& v,
00135                                vdgl_digital_curve_sptr& dc1,
00136                                vdgl_digital_curve_sptr& dc2)
00137 {
00138   vdgl_edgel_chain_sptr ec = interpolator_->get_edgel_chain();
00139   vdgl_edgel_chain_sptr ec1, ec2;
00140   if (! ec->split(v->x(), v->y(), ec1, ec2)) return false;
00141   dc1 = new vdgl_digital_curve(new vdgl_interpolator_linear(ec1));
00142   dc2 = new vdgl_digital_curve(new vdgl_interpolator_linear(ec2));
00143   return true;
00144 }
00145 
00146 //: scan all the points on the curve and compute the bounds.
00147 void vdgl_digital_curve::compute_bounding_box() const
00148 {
00149   set_bounding_box(   interpolator_->get_min_x(), interpolator_->get_min_y());
00150   add_to_bounding_box(interpolator_->get_max_x(), interpolator_->get_max_y());
00151 }
00152 
00153 bool vdgl_digital_curve::operator==(const vdgl_digital_curve &other) const
00154 {
00155   if (this==&other)
00156     return true;
00157   //same order of interpolation?
00158   if (this->order() != other.order())
00159     return false;
00160   //are the edgel chains equal?
00161   vdgl_edgel_chain_sptr ec = this->get_interpolator()->get_edgel_chain();
00162   vdgl_edgel_chain_sptr eco = other.get_interpolator()->get_edgel_chain();
00163   bool edgel_chains_eq = *ec == *eco;
00164   //are the endpoints equal
00165   bool epts_eq = this->vsol_curve_2d::endpoints_equal(other);
00166   return edgel_chains_eq&&epts_eq;
00167 }
00168 
00169 bool vdgl_digital_curve::operator==(const vsol_spatial_object_2d& obj) const
00170 {
00171   return
00172     obj.cast_to_curve() && obj.cast_to_curve()->cast_to_vdgl_digital_curve() &&
00173     *this == *obj.cast_to_curve()->cast_to_vdgl_digital_curve();
00174 }
00175 
00176 //----------------------------------------------------------------
00177 // ================   Binary I/O Methods ========================
00178 //----------------------------------------------------------------
00179 
00180 //: Binary save self to stream.
00181 void vdgl_digital_curve::b_write(vsl_b_ostream &os) const
00182 {
00183   vsl_b_write(os, version());
00184   vsl_b_write(os, this->order());
00185   vsl_b_write(os, this->get_interpolator()->get_edgel_chain());
00186   vsl_b_write(os, true);
00187 }
00188 
00189 //: Binary load self from stream (not typically used)
00190 void vdgl_digital_curve::b_read(vsl_b_istream &is)
00191 {
00192   if (!is)
00193     return;
00194   short ver;
00195   vsl_b_read(is, ver);
00196   switch (ver)
00197   {
00198    default:
00199     assert(!"vdgl_digital_curve I/O: version should be 1");
00200    case 1:
00201     short order;
00202     vsl_b_read(is, order);
00203     vdgl_edgel_chain_sptr ec;
00204     vsl_b_read(is, ec);
00205     bool endpoints;
00206     vsl_b_read(is, endpoints);
00207     assert(endpoints);
00208     if (ec)
00209     {
00210       switch (order)
00211       {
00212        case 1:
00213         interpolator_ = new vdgl_interpolator_linear(ec);
00214         break;
00215        case 3:
00216         interpolator_ = new vdgl_interpolator_cubic(ec);
00217         break;
00218        default:
00219         return;
00220       }
00221     }
00222   }
00223 }
00224 
00225 //: Return IO version number;
00226 short vdgl_digital_curve::version() const
00227 {
00228   return 1;
00229 }
00230 
00231 //: Print an ascii summary to the stream
00232 void vdgl_digital_curve::print_summary(vcl_ostream &os) const
00233 {
00234   os << *this;
00235 }
00236 
00237 //: Binary save vdgl_digital_curve* to stream.
00238 void vsl_b_write(vsl_b_ostream &os, const vdgl_digital_curve* dc)
00239 {
00240   if (!dc){
00241     vsl_b_write(os, false); // Indicate null pointer stored
00242   }
00243   else{
00244     vsl_b_write(os,true); // Indicate non-null pointer stored
00245     dc->b_write(os);
00246   }
00247 }
00248 
00249 //: Binary load vdgl_digital_curve* from stream.
00250 void vsl_b_read(vsl_b_istream &is, vdgl_digital_curve* &dc)
00251 {
00252   delete dc;
00253   bool not_null_ptr;
00254   vsl_b_read(is, not_null_ptr);
00255   if (not_null_ptr) {
00256     dc = new vdgl_digital_curve();
00257     dc->b_read(is);
00258   }
00259   else
00260     dc = 0;
00261 }
00262 
00263 //: Print human readable summary of vdgl_digital_curve* to a stream.
00264 void vsl_print_summary(vcl_ostream &os, const vdgl_digital_curve* dc)
00265 {
00266   os << *dc;
00267 }
00268 
00269 //: Stream operator
00270 vcl_ostream& operator<<(vcl_ostream& s, const vdgl_digital_curve& dc)
00271 {
00272   return s << "[order: " << dc.order() << ' ' << *(dc.get_interpolator()->get_edgel_chain()) << ']';
00273 }