00001 #include "bdgl_curve_algs.h"
00002
00003
00004 #include <vcl_cmath.h>
00005 #include <vcl_cstdlib.h>
00006 #include <vcl_cassert.h>
00007 #include <vcl_iostream.h>
00008 #include <vnl/vnl_numeric_traits.h>
00009 #include <vnl/vnl_double_2.h>
00010 #include <vnl/vnl_double_3.h>
00011 #include <vnl/vnl_math.h>
00012 #include <vgl/vgl_line_2d.h>
00013 #include <vgl/vgl_point_2d.h>
00014 #include <vgl/vgl_homg_point_2d.h>
00015 #include <vgl/vgl_box_2d.h>
00016 #include <vgl/vgl_intersection.h>
00017 #include <vgl/algo/vgl_homg_operators_2d.h>
00018 #include <vsol/vsol_box_2d.h>
00019 #include <vdgl/vdgl_edgel_chain.h>
00020 #include <vdgl/vdgl_interpolator.h>
00021 #include <vdgl/vdgl_interpolator_linear.h>
00022 #include <vdgl/vdgl_digital_curve.h>
00023 #include <vnl/algo/vnl_gaussian_kernel_1d.h>
00024
00025 const double bdgl_curve_algs::tol = 1e-16;
00026 const double bdgl_curve_algs::max_edgel_sep = 2.0;
00027
00028 const double bdgl_curve_algs::synthetic = 0;
00029
00030
00031
00032 bdgl_curve_algs::~bdgl_curve_algs()
00033 {
00034 }
00035
00036
00037
00038
00039
00040
00041
00042 double bdgl_curve_algs::closest_point(vdgl_digital_curve_sptr const& dc,
00043 const double x, const double y)
00044 {
00045 if (!dc)
00046 {
00047 vcl_cout<<"In bdgl_curve_algs::closest_point(..) -"
00048 << " warning, null digital curve\n";
00049 return 0;
00050 }
00051 vdgl_interpolator_sptr interp = dc->get_interpolator();
00052 vdgl_edgel_chain_sptr ec = interp->get_edgel_chain();
00053 int index = closest_point(ec, x, y);
00054 double parm = index/ec->size();
00055 return parm;
00056 }
00057
00058
00059
00060
00061
00062
00063
00064 int bdgl_curve_algs::closest_point(vdgl_edgel_chain_sptr const& ec,
00065 const double x, const double y)
00066 {
00067 if (!ec)
00068 {
00069 vcl_cout<<"In bdgl_curve_algs::closest_point(..) - warning, null chain\n";
00070 return 0;
00071 }
00072
00073 double mind = vnl_numeric_traits<double>::maxval;
00074 int N =ec->size(), imin = 0;
00075
00076 for (int i = 0; i<N; i++)
00077 {
00078 vdgl_edgel ed = ec->edgel(i);
00079 double d = vcl_sqrt((ed.x()-x)*(ed.x()-x) + (ed.y()-y)*(ed.y()-y));
00080 if (d<mind)
00081 {
00082 mind = d;
00083 imin = i;
00084 }
00085 }
00086 return imin;
00087 }
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 bool bdgl_curve_algs::closest_point(vdgl_digital_curve_sptr const& dc,
00098 const double x, const double y,
00099 double& xc, double& yc)
00100 {
00101 if (!dc)
00102 {
00103 vcl_cout<<"In bdgl_curve_algs::closest_point(..) - warning, null curve\n";
00104 return false;
00105 }
00106 vdgl_interpolator_sptr interp = dc->get_interpolator();
00107 vdgl_edgel_chain_sptr ec = interp->get_edgel_chain();
00108 int index = bdgl_curve_algs::closest_point(ec, x, y);
00109 xc = (*ec)[index].x();
00110 yc = (*ec)[index].y();
00111 return true;
00112 }
00113
00114
00115
00116 static double interpolate_segment(vnl_double_2& p0,
00117 vnl_double_2& p1,
00118 vnl_double_2& p,
00119 vnl_double_2& pc)
00120 {
00121 double Dx = p1[0]-p0[0], Dy = p1[1]-p0[1];
00122 double dx = p[0]-p0[0], dy = p[1]-p0[1];
00123 double den = Dx*Dx + Dy*Dy;
00124 if (den<bdgl_curve_algs::tol)
00125 {
00126 pc = p0;
00127 return 0;
00128 }
00129 double t = (dx*Dx + Dy*dy)/den;
00130
00131 if (t<0)
00132 t=0.0;
00133 if (t>1.0)
00134 t=1.0;
00135 pc[0] = t*Dx + p0[0]; pc[1] = t*Dy + p0[1];
00136 return t;
00137 }
00138
00139
00140
00141
00142
00143
00144
00145 bool bdgl_curve_algs::closest_point_near(vdgl_edgel_chain_sptr const& ec,
00146 const int index,
00147 const double x,
00148 const double y,
00149 double & xc,
00150 double & yc)
00151 {
00152 int last = ec->size()-1;
00153 vnl_double_2 p(x, y);
00154 vnl_double_2 p0, p1, pc;
00155
00156 if (index<0)
00157 return false;
00158 else if (index<last)
00159 {
00160 p0[0]=(*ec)[index].x();
00161 p0[1]=(*ec)[index].y();
00162 p1[0]=(*ec)[index+1].x();
00163 p1[1]=(*ec)[index+1].y();
00164 }
00165 else if (index==last)
00166 {
00167 p0[0]=(*ec)[index-1].x();
00168 p0[1]=(*ec)[index-1].y();
00169 p1[0]=(*ec)[index].x();
00170 p1[1]=(*ec)[index].y();
00171 }
00172 else
00173 return false;
00174
00175 double t = interpolate_segment(p0, p1, p, pc);
00176 vcl_cout << "At " << p << " t = " << t << '\n';
00177 xc = pc[0]; yc = pc[1];
00178 return true;
00179 }
00180
00181
00182
00183
00184 vdgl_digital_curve_sptr bdgl_curve_algs::reverse(vdgl_digital_curve_sptr const& dc)
00185 {
00186 if (!dc)
00187 return 0;
00188 vdgl_interpolator_sptr intrp = dc->get_interpolator();
00189 vdgl_edgel_chain_sptr ec = intrp->get_edgel_chain();
00190 int N = ec->size();
00191 vdgl_edgel_chain_sptr rev_ec = new vdgl_edgel_chain();
00192 for (int i = 0; i<N; i++)
00193 rev_ec->add_edgel((*ec)[N-1-i]);
00194 vdgl_interpolator_sptr rev_intrp = new vdgl_interpolator_linear(rev_ec);
00195 vdgl_digital_curve_sptr rev_dc = new vdgl_digital_curve(rev_intrp);
00196 return rev_dc;
00197 }
00198
00199 bool bdgl_curve_algs::intersect_bounding_box(vdgl_digital_curve_sptr const& dc,
00200 vgl_line_2d<double> & line)
00201 {
00202 vsol_box_2d_sptr bb = dc->get_bounding_box();
00203 if (!bb)
00204 return false;
00205 vgl_box_2d<double> box(bb->get_min_x(), bb->get_max_x(),
00206 bb->get_min_y(), bb->get_max_y());
00207 vgl_point_2d<double> p0, p1;
00208 if (vgl_intersection(box, line, p0, p1))
00209 return true;
00210 return false;
00211 }
00212
00213
00214
00215 static bool intersect_crossing(vnl_double_3& line_coefs,
00216 vnl_double_3& p0,
00217 vnl_double_3& p1,
00218 vnl_double_3& inter)
00219 {
00220
00221 vnl_double_3 lv01 = vnl_cross_3d(p0, p1);
00222
00223
00224 inter = vnl_cross_3d(lv01, line_coefs);
00225
00226 return vcl_fabs(inter[2]) >= bdgl_curve_algs::tol;
00227 }
00228
00229
00230
00231 static bool intersect_line_helper(vdgl_edgel_chain const& ec,
00232 vnl_double_3& lv,
00233 double dist1, double dist2,
00234 int index1, int index2,
00235 vcl_vector<vgl_point_2d<double> >& pts)
00236 {
00237 int di = (index2 - index1);
00238 if (di<1) {
00239 vcl_cout << "In bdgl_curve_algs::intersect_line_helper -"
00240 << " invalid curve segment\n";
00241 return false;
00242 }
00243
00244 if (vcl_fabs(dist2)<bdgl_curve_algs::tol || dist1*dist2<0.0) {
00245
00246 if (di==1) {
00247
00248 vdgl_edgel const& e1 = ec[index1];
00249 vdgl_edgel const& e2 = ec[index2];
00250 vnl_double_3 p1(e1.get_x(), e1.get_y(), 1.0);
00251 vnl_double_3 p2(e2.get_x(), e2.get_y(), 1.0);
00252
00253 vnl_double_3 inter;
00254 if (intersect_crossing(lv, p1, p2, inter)) {
00255 vgl_point_2d<double> p(inter[0]/inter[2], inter[1]/inter[2]);
00256 pts.push_back(p);
00257 return true;
00258 }
00259 return false;
00260 }
00261 }
00262 else{
00263 if (di==1) return false;
00264 if ((di*bdgl_curve_algs::max_edgel_sep)<vcl_fabs(dist1+dist2)) return false;
00265 }
00266
00267 int mid_index = index1 + di/2;
00268 vnl_double_3 mid_point(ec[mid_index].get_x(), ec[mid_index].get_y(), 1.0);
00269 double mid_dist = dot_product(mid_point, lv);
00270 bool i1 = intersect_line_helper(ec, lv, dist1, mid_dist, index1, mid_index, pts);
00271 bool i2 = intersect_line_helper(ec, lv, mid_dist, dist2, mid_index, index2, pts);
00272 return i1 || i2;
00273 }
00274
00275
00276
00277
00278
00279
00280
00281 bool bdgl_curve_algs::intersect_line_fast(vdgl_digital_curve_sptr const& dc,
00282 vgl_line_2d<double> & line,
00283 vcl_vector<vgl_point_2d<double> >& pts)
00284 {
00285 if (!dc)
00286 {
00287 vcl_cout << "In bdgl_curve_algs::intersect_line_fast - null curve\n";
00288 return false;
00289 }
00290 vdgl_interpolator_sptr interp = dc->get_interpolator();
00291 vdgl_edgel_chain_sptr ec = interp->get_edgel_chain();
00292
00293
00294
00295 line.normalize();
00296 vnl_double_3 lv(line.a(), line.b(), line.c());
00297
00298
00299 vdgl_edgel const& e1 = (*ec)[0];
00300 vdgl_edgel const& e2 = (*ec)[ec->size()-1];
00301
00302 vnl_double_3 p1(e1.get_x(), e1.get_y(), 1.0);
00303 vnl_double_3 p2(e2.get_x(), e2.get_y(), 1.0);
00304
00305 double dist1 = dot_product(p1, lv);
00306 double dist2 = dot_product(p2, lv);
00307
00308 bool intersection = false;
00309
00310
00311 if (vcl_fabs(dist1)<bdgl_curve_algs::tol) {
00312 vdgl_edgel const& e = (*ec)[1];
00313 vnl_double_3 p(e.get_x(), e.get_y(), 1.0);
00314 vnl_double_3 inter;
00315 if (intersect_crossing(lv, p1, p, inter)) {
00316 vgl_point_2d<double> p(inter[0]/inter[2], inter[1]/inter[2]);
00317 pts.push_back(p);
00318 intersection = true;
00319 }
00320 }
00321
00322 return intersect_line_helper(*ec, lv, dist1, dist2, 0, ec->size()-1, pts) ||
00323 intersection;
00324 }
00325
00326
00327
00328
00329
00330
00331 bool bdgl_curve_algs::intersect_line(vdgl_digital_curve_sptr const& dc,
00332 vgl_line_2d<double>& line,
00333 vcl_vector<vgl_point_2d<double> >& pts)
00334 {
00335 if (!dc)
00336 {
00337 vcl_cout << "In bdgl_curve_algs::intersect_line - null curve\n";
00338 return false;
00339 }
00340
00341
00342
00343
00344
00345
00346 bool intersection = false;
00347 vnl_double_3 lv(line.a(), line.b(), line.c());
00348
00349
00350
00351 double t=0, dt = 1/(10*dc->length());
00352 vnl_double_3 p0(dc->get_x(t), dc->get_y(t), 1.0), p1;
00353 for (double t=dt; t<=1.0; t+=dt)
00354 {
00355 p1[0]=dc->get_x(t); p1[1]=dc->get_y(t); p1[2]= 1.0;
00356 double sign0 = dot_product(p0, lv);
00357 double sign1 = dot_product(p1, lv);
00358 if (vcl_fabs(sign0)<bdgl_curve_algs::tol||
00359 vcl_fabs(sign1)<bdgl_curve_algs::tol||sign0*sign1<=0)
00360 {
00361 vnl_double_3 inter;
00362 if (intersect_crossing(lv, p0, p1, inter))
00363 {
00364 vgl_point_2d<double> p(inter[0]/inter[2], inter[1]/inter[2]);
00365 pts.push_back(p);
00366 intersection = true;
00367 }
00368 }
00369 p0=p1;
00370 }
00371 return intersection;
00372 }
00373
00374
00375
00376
00377
00378
00379 static double interpolate_parameter(const double t0, const double t1,
00380 vnl_double_3& p0,
00381 vnl_double_3& p1,
00382 vnl_double_3& pt)
00383 {
00384 if (vcl_fabs(p0[2])<bdgl_curve_algs::tol)
00385 return t0;
00386 if (vcl_fabs(p1[2])<bdgl_curve_algs::tol)
00387 return t0;
00388 if (vcl_fabs(pt[2])<bdgl_curve_algs::tol)
00389 return t0;
00390 double x0 = p0[0]/p0[2], y0 = p0[1]/p0[2];
00391 double x1 = p1[0]/p1[2], y1 = p1[1]/p1[2];
00392 double xt = pt[0]/pt[2], yt = pt[1]/pt[2];
00393 double d01 = vcl_sqrt((x1-x0)*(x1-x0) + (y1-y0)*(y1-y0));
00394 double d0t = vcl_sqrt((xt-x0)*(xt-x0) + (yt-y0)*(yt-y0));
00395 double r = d0t/d01;
00396 double dt = t1-t0;
00397 return t0 + r*dt;
00398 }
00399
00400
00401
00402 static bool intersect_line_helper(vdgl_edgel_chain const& ec,
00403 vnl_double_3& lv,
00404 double dist1, double dist2,
00405 int index1, int index2,
00406 vcl_vector<double>& indices)
00407 {
00408 int di = (index2 - index1);
00409 if (di<1) {
00410 vcl_cout << "In bdgl_curve_algs::intersect_line_helper -"
00411 << " invalid curve segment\n";
00412 return false;
00413 }
00414
00415 if (vcl_fabs(dist2)<bdgl_curve_algs::tol || dist1*dist2<0.0) {
00416
00417 if (di==1) {
00418
00419 vdgl_edgel const& e1 = ec[index1];
00420 vdgl_edgel const& e2 = ec[index2];
00421 vnl_double_3 p1(e1.get_x(), e1.get_y(), 1.0);
00422 vnl_double_3 p2(e2.get_x(), e2.get_y(), 1.0);
00423
00424 vnl_double_3 inter;
00425 if (intersect_crossing(lv, p1, p2, inter)) {
00426 double param_step = 1.0/(ec.size()-1);
00427 double ti = interpolate_parameter(index1*param_step, index2*param_step,
00428 p1, p2, inter);
00429 indices.push_back(ti);
00430 return true;
00431 }
00432 return false;
00433 }
00434 }
00435 else{
00436 if (di==1) return false;
00437 if ((di*bdgl_curve_algs::max_edgel_sep)<vcl_fabs(dist1+dist2)) return false;
00438 }
00439
00440 int mid_index = index1 + di/2;
00441 vnl_double_3 mid_point(ec[mid_index].get_x(), ec[mid_index].get_y(), 1.0);
00442 double mid_dist = dot_product(mid_point, lv);
00443
00444 bool i1 = intersect_line_helper(ec, lv, dist1, mid_dist, index1, mid_index, indices);
00445 bool i2 = intersect_line_helper(ec, lv, mid_dist, dist2, mid_index, index2, indices);
00446 return i1 || i2;
00447 }
00448
00449
00450
00451
00452
00453
00454
00455
00456 bool bdgl_curve_algs::intersect_line_fast(vdgl_digital_curve_sptr const& dc,
00457 vgl_line_2d<double> & line,
00458 vcl_vector<double>& indices)
00459 {
00460 if (!dc)
00461 {
00462 vcl_cout << "In bdgl_curve_algs::intersect_line_fast - null curve\n";
00463 return false;
00464 }
00465 vdgl_interpolator_sptr interp = dc->get_interpolator();
00466 vdgl_edgel_chain_sptr ec = interp->get_edgel_chain();
00467
00468
00469
00470 line.normalize();
00471 vnl_double_3 lv(line.a(), line.b(), line.c());
00472
00473
00474 vdgl_edgel const& e1 = (*ec)[0];
00475 vdgl_edgel const& e2 = (*ec)[ec->size()-1];
00476
00477 vnl_double_3 p1(e1.get_x(), e1.get_y(), 1.0);
00478 vnl_double_3 p2(e2.get_x(), e2.get_y(), 1.0);
00479
00480 double dist1 = dot_product(p1, lv);
00481 double dist2 = dot_product(p2, lv);
00482
00483 bool intersection = false;
00484
00485
00486 if (vcl_fabs(dist1)<bdgl_curve_algs::tol) {
00487 vdgl_edgel const& e = (*ec)[1];
00488 vnl_double_3 p(e.get_x(), e.get_y(), 1.0);
00489 vnl_double_3 inter;
00490 if (intersect_crossing(lv, p1, p, inter)) {
00491 double param_step = 1.0/(ec->size()-1);
00492 double ti = interpolate_parameter(0.0, param_step, p1, p, inter);
00493 indices.push_back(ti);
00494 intersection = true;
00495 }
00496 }
00497
00498 return intersect_line_helper(*ec, lv, dist1, dist2, 0, ec->size()-1, indices) ||
00499 intersection;
00500 }
00501
00502
00503
00504
00505
00506
00507
00508 bool bdgl_curve_algs::intersect_line(vdgl_digital_curve_sptr const& dc,
00509 vgl_line_2d<double>& line,
00510 vcl_vector<double>& indices)
00511 {
00512 if (!dc)
00513 {
00514 vcl_cout << "In bdgl_curve_algs::intersect_line - null curve\n";
00515 return false;
00516 }
00517
00518
00519
00520
00521
00522
00523 bool intersection = false;
00524 vnl_double_3 lv(line.a(), line.b(), line.c());
00525
00526
00527
00528 double t=0, dt = 1/(10*dc->length());
00529 vnl_double_3 p0(dc->get_x(t), dc->get_y(t), 1.0), p1;
00530 for (double t=dt; t<=1.0; t+=dt)
00531 {
00532 p1[0]=dc->get_x(t); p1[1]=dc->get_y(t); p1[2]= 1.0;
00533 double sign0 = dot_product(p0, lv);
00534 double sign1 = dot_product(p1, lv);
00535 if (vcl_fabs(sign0)<bdgl_curve_algs::tol||
00536 vcl_fabs(sign1)<bdgl_curve_algs::tol||sign0*sign1<=0)
00537 {
00538 vnl_double_3 inter;
00539 if (intersect_crossing(lv, p0, p1, inter))
00540 {
00541 double ti = interpolate_parameter(t, t+dt, p0, p1, inter);
00542 indices.push_back(ti);
00543 intersection = true;
00544 }
00545 }
00546 p0=p1;
00547 }
00548 return intersection;
00549 }
00550
00551
00552
00553 bool
00554 bdgl_curve_algs::match_intersection(vdgl_digital_curve_sptr const& dc,
00555 vgl_line_2d<double>& line,
00556 vgl_point_2d<double> const& ref_point,
00557 double ref_gradient_angle,
00558 vgl_point_2d<double>& point)
00559 {
00560 double angle_thresh = 7.0;
00561 double angle_tol = 12.5;
00562 if (!dc)
00563 return false;
00564 double la = line.slope_degrees();
00565 if (la<0)
00566 la+=180;
00567 vcl_vector<double> indices;
00568 if (!bdgl_curve_algs::intersect_line(dc, line, indices))
00569 return false;
00570 vgl_homg_point_2d<double> rph(ref_point.x(), ref_point.y());
00571 double dist = 1e10;
00572 bool found_valid_intersection = false;
00573 for (vcl_vector<double>::iterator iit = indices.begin();
00574 iit != indices.end(); iit++)
00575 {
00576 double grad_angle = dc->get_theta(*iit);
00577 if (vcl_fabs(ref_gradient_angle-grad_angle)>angle_tol)
00578 continue;
00579 double ca = dc->get_tangent_angle(*iit);
00580 if (ca<0)
00581 ca+=180;
00582 double delt = vcl_fabs(vcl_sin(vcl_fabs(vnl_math::pi_over_180*(ca-la)))*vnl_math::deg_per_rad);
00583 if (delt<angle_thresh)
00584 continue;
00585 vgl_homg_point_2d<double> ph(dc->get_x(*iit), dc->get_y(*iit));
00586 double d = vgl_homg_operators_2d<double>::distance_squared(rph, ph);
00587 d = vcl_sqrt(d);
00588 found_valid_intersection = true;
00589 if (d<dist)
00590 {
00591
00592
00593 dist = d;
00594 point = vgl_point_2d<double>(dc->get_x(*iit), dc->get_y(*iit));
00595 }
00596 }
00597 return found_valid_intersection;
00598 }
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614 bool bdgl_curve_algs::line_gen(const float xs, const float ys,
00615 const float xe, const float ye,
00616 bool& init, bool& done,
00617 float& x, float& y)
00618 {
00619 assert(xs >= 0.0f); assert(ys >= 0.0f);
00620 const float pix_edge = 1.0f;
00621 static float xi=0, yi=0;
00622 if (init)
00623 {
00624 xi = xs;
00625 yi = ys;
00626 x = (float)(xi/pix_edge);
00627 y = (float)(yi/pix_edge);
00628 init = false;
00629 return true;
00630 }
00631 if (done) return false;
00632 float dx = xe-xs;
00633 float dy = ye-ys;
00634 float mag = vcl_sqrt(dx*dx + dy*dy);
00635 if (mag<pix_edge)
00636 {
00637 x = (float)xe; y = (float)ye;
00638 done = true;
00639 return true;
00640 }
00641 float delta = (0.5f*pix_edge)/mag;
00642
00643 int xp = int(xi/pix_edge);
00644 int yp = int(yi/pix_edge);
00645
00646 for (int i = 0; i<3; i++)
00647 {
00648 xi += dx*delta;
00649 yi += dy*delta;
00650
00651 if ((xe>=xs&&xi>xe)||(xe<=xs&&xi<xe)||(ye>=ys&&yi>ye)||(ye<=ys&&yi<ye))
00652 {
00653 x = (float)xe; y = (float)ye;
00654 done = true;
00655 return true;
00656 }
00657
00658 x = (float)(xi/pix_edge);
00659 y = (float)(yi/pix_edge);
00660 if (2*vcl_abs(int(x)-xp)>pix_edge || 2*vcl_abs(int(y)-yp)>pix_edge)
00661 return true;
00662 }
00663 vcl_cout << "in bdgl_curve_algs::line_gen - shouldn't happen\n";
00664 return false;
00665 }
00666
00667
00668
00669
00670
00671 int bdgl_curve_algs::add_straight_edgels(vdgl_edgel_chain_sptr const& ec,
00672 const double xe, const double ye,
00673 bool debug)
00674 {
00675 assert (ec);
00676 assert (ec->size() > 0);
00677 int Npix = 0, last = ec->size()-1;
00678
00679 float xs = float((*ec)[last].x()), ys = float((*ec)[last].y());
00680 bool first = true, init = true, done = false;
00681 float x, y;
00682 while (bdgl_curve_algs::line_gen(xs, ys, float(xe), float(ye), init, done, x, y))
00683 if (!first)
00684 {
00685 vdgl_edgel ed(x, y, bdgl_curve_algs::synthetic);
00686 ec->add_edgel(ed);
00687 Npix++;
00688 if (debug)
00689 vcl_cout << "Adding edgel " << ed << '\n';
00690 }
00691 else
00692 first = false;
00693 return Npix;
00694 }
00695
00696
00697
00698
00699 int bdgl_curve_algs::closest_end(vdgl_edgel_chain_sptr const & ec,
00700 const double x, const double y)
00701 {
00702 if (!ec)
00703 {
00704 vcl_cout << "In bdgl_curve_algs::closest_end - null edgel chain\n";
00705 return 0;
00706 }
00707 int N = ec->size();
00708 if (!N)
00709 {
00710 vcl_cout << "In bdgl_curve_algs::closest_end - no edgels in chain\n";
00711 return 0;
00712 }
00713 double x0 = (*ec)[0].x(), y0=(*ec)[0].y();
00714 double xn = (*ec)[N-1].x(), yn=(*ec)[N-1].y();
00715 double d0 = vcl_sqrt((x0-x)*(x0-x)+ (y0-y)*(y0-y));
00716 double dn = vcl_sqrt((xn-x)*(xn-x)+ (yn-y)*(yn-y));
00717 if (d0<dn)
00718 return 0;
00719 return N;
00720 }
00721
00722
00723
00724 void bdgl_curve_algs::
00725 smooth_curve(vcl_vector<vgl_point_2d<double> > &curve,double sigma)
00726 {
00727 vnl_gaussian_kernel_1d gauss_1d(sigma);
00728 curve.insert(curve.begin(),curve[0]);
00729 curve.insert(curve.begin(),curve[0]);
00730 curve.insert(curve.begin(),curve[0]);
00731
00732 curve.insert(curve.end(),curve[curve.size()-1]);
00733 curve.insert(curve.end(),curve[curve.size()-1]);
00734 curve.insert(curve.end(),curve[curve.size()-1]);
00735 double sum=gauss_1d[0];
00736 for (int i=1;i<gauss_1d.width();i++)
00737 sum+=2*gauss_1d[i];
00738
00739 for (unsigned int i=3; i+3<curve.size(); ++i)
00740 {
00741 double x=curve[i-3].x()*gauss_1d[3] + curve[i-2].x()*gauss_1d[2]+
00742 curve[i-1].x()*gauss_1d[1] + curve[i ].x()*gauss_1d[0]+
00743 curve[i+1].x()*gauss_1d[1] + curve[i+2].x()*gauss_1d[2]+
00744 curve[i+3].x()*gauss_1d[3];
00745 double y=curve[i-3].y()*gauss_1d[3] + curve[i-2].y()*gauss_1d[2]+
00746 curve[i-1].y()*gauss_1d[1] + curve[i ].y()*gauss_1d[0]+
00747 curve[i+1].y()*gauss_1d[1] + curve[i+2].y()*gauss_1d[2]+
00748 curve[i+3].y()*gauss_1d[3];
00749 x/=sum;
00750 y/=sum;
00751 curve[i].set(x,y);
00752 }
00753 }
00754
00755 vdgl_digital_curve_sptr bdgl_curve_algs::
00756 create_digital_curves(vcl_vector<vgl_point_2d<double> > & curve)
00757 {
00758 vdgl_edgel_chain_sptr vec;
00759 vec= new vdgl_edgel_chain;
00760 for (unsigned int j=0; j<curve.size(); ++j)
00761 {
00762 vdgl_edgel el(curve[j].x(),curve[j].y(), 0,0 );
00763 vec->add_edgel(el);
00764 }
00765 vdgl_interpolator_sptr interp= new vdgl_interpolator_linear(vec);
00766 vdgl_digital_curve_sptr dc = new vdgl_digital_curve(interp);
00767 return dc;
00768 }
00769