Go to the documentation of this file.00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005
00006
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
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
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
00158 if (this->order() != other.order())
00159 return false;
00160
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
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
00178
00179
00180
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
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
00226 short vdgl_digital_curve::version() const
00227 {
00228 return 1;
00229 }
00230
00231
00232 void vdgl_digital_curve::print_summary(vcl_ostream &os) const
00233 {
00234 os << *this;
00235 }
00236
00237
00238 void vsl_b_write(vsl_b_ostream &os, const vdgl_digital_curve* dc)
00239 {
00240 if (!dc){
00241 vsl_b_write(os, false);
00242 }
00243 else{
00244 vsl_b_write(os,true);
00245 dc->b_write(os);
00246 }
00247 }
00248
00249
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
00264 void vsl_print_summary(vcl_ostream &os, const vdgl_digital_curve* dc)
00265 {
00266 os << *dc;
00267 }
00268
00269
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 }