contrib/oxl/osl/osl_break_edge.cxx
Go to the documentation of this file.
00001 // This is oxl/osl/osl_break_edge.cxx
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005 //:
00006 // \file
00007 // \author fsm
00008 
00009 #include "osl_break_edge.h"
00010 
00011 #include <vcl_cassert.h>
00012 #include <osl/osl_edge.h>
00013 #include <osl/osl_ortho_regress.h>
00014 
00015 void osl_break_edge(osl_edge const *in,
00016                     vcl_vector<unsigned> const &where,
00017                     vcl_list<osl_edge*> *broken)
00018 {
00019   assert(broken);
00020   assert(in);
00021   float const *x = in->GetX();
00022   float const *y = in->GetY();
00023   assert(!where.empty());
00024   assert(where.front() == 0);
00025   assert(where.back()+1 == in->size());
00026 
00027   // make array of vertices, one for each break.
00028   vcl_vector<osl_vertex*> verts;
00029   verts.push_back(in->GetV1()); // maintain topology.
00030   for (unsigned int i=1; i+1<where.size(); ++i)
00031     verts.push_back(new osl_vertex(x[where[i]], y[where[i]]));
00032   verts.push_back(in->GetV2()); // maintain topology.
00033 
00034   // make new edges and push them onto the given list.
00035   for (unsigned int i=0; i+1<where.size(); ++i) {
00036     osl_edge *fragment = new osl_edge(where[i+1]-where[i] + 1, verts[i], verts[i+1]);
00037     for (unsigned int j=0; j<fragment->size(); ++j) {
00038       fragment->SetX(x[j + where[i]], j);
00039       fragment->SetY(y[j + where[i]], j);
00040     }
00041     broken->push_back(fragment);
00042   }
00043 }
00044 
00045 void osl_break_edge(osl_edge const *in,
00046                     vcl_list<osl_edge*> *out_ptr,
00047                     double threshold,
00048                     unsigned nbhd_size)
00049 {
00050   assert(in!=0);
00051 
00052   float const *x = in->GetX();
00053   float const *y = in->GetY();
00054   unsigned n = in->size();
00055 
00056   osl_ortho_regress fitter;
00057 
00058   // decide where to break the edge.
00059   vcl_vector<unsigned> breaks;
00060 
00061   breaks.push_back(0);   // first edgel
00062   for (unsigned int pos=nbhd_size; pos+nbhd_size<n; ++pos) {
00063 
00064     fitter.reset(); // we could make this more efficient.
00065     fitter.add_points(&x[pos-nbhd_size], &y[pos-nbhd_size], 2*nbhd_size+1);
00066 
00067     double a, b, c;
00068     fitter.fit(&a, &b, &c);
00069 
00070     if (fitter.rms_cost(a, b, c) > threshold)
00071       breaks.push_back(pos);
00072   }
00073   breaks.push_back(n-1); // last edgel
00074 
00075   osl_break_edge(in, breaks, out_ptr);
00076 }
00077 
00078 //--------------------------------------------------------------------------------
00079 
00080 // defunct
00081 #if 0
00082   breaks.push_back(0);   // first edgel
00083   while (true) {
00084     int pos = breaks.back();
00085     if (pos+1 >= n)
00086       break; // reached the end - done.
00087 
00088     // else, there are at least two edgels available, pos and pos+1 :
00089 
00090     fitter.reset();
00091     fitter.add_point(x[pos], y[pos]); ++pos;
00092     fitter.add_point(x[pos], y[pos]); ++pos;
00093     for (; pos<n; ++pos) {
00094       fitter.add_point(x[pos], y[pos]);
00095       double a, b, c;
00096       fitter.fit(&a, &b, &c);
00097       if (fitter.rms_cost(a, b, c) > threshold)
00098         break;
00099     }
00100 
00101     if (pos<n)
00102       breaks.push_back(pos);
00103     else {
00104       breaks.push_back(n-1);
00105       break;
00106     }
00107   }
00108   //breaks.push_back(n-1); // last edgel
00109 #endif