Exemple #1
0
// simplifyDP():
//  This is the Douglas-Peucker recursive simplification routine
//  It just marks vertices that are part of the simplified polyline
//  for approximating the polyline subchain v[j] to v[k].
//    Input:  tol = approximation tolerance
//            v[] = polyline array of vertex points
//            j,k = indices for the subchain v[j] to v[k]
//    Output: mk[] = array of markers matching vertex array v[]
void Contour::simplifyDP(float tol, std::vector<frsmPoint> &v, int j, int k, std::vector<bool> &mk)
{
  if (k <= j + 1) // there is nothing to simplify
    return;

  // check for adequate approximation by segment S from v[j] to v[k]
  int maxi = j; // index of vertex farthest from segment
  float max_dist_to_seg = 0;
  // test each vertex v[i] for max distance from segment v[j]-v[k]
  for (int i = j + 1; i < k; i++) {
    double dist_to_seg = frsm_dist_to_segment(&v[i], &v[j], &v[k]);
    if (dist_to_seg <= max_dist_to_seg)
      continue;
    else {
      // v[i] is a new max vertex
      maxi = i;
      max_dist_to_seg = dist_to_seg;
    }
  }
  if (max_dist_to_seg > tol) // error is worse than the tolerance
  {
    // split the polyline at the farthest vertex
    mk[maxi] = true; // mark v[maxi] for the simplified polyline
    // recursively simplify the two subpolylines at v[maxi]
    simplifyDP(tol, v, j, maxi, mk); // polyline v[j] to v[maxi]
    simplifyDP(tol, v, maxi, k, mk); // polyline v[maxi] to v[k]
  }
  // else the approximation is OK, so ignore intermediate vertices
  return;
}
static void simplifyDP(float tol, ofPoint* v, int j, int k, int* mk ){
    if (k <= j+1) // there is nothing to simplify
        return;

    // check for adequate approximation by segment S from v[j] to v[k]
    int     maxi	= j;          // index of vertex farthest from S
    float   maxd2	= 0;         // distance squared of farthest vertex
    float   tol2	= tol * tol;  // tolerance squared
    Segment S		= {v[j], v[k]};  // segment from v[j] to v[k]
    ofPoint u;
	u				= S.P1 - S.P0;   // segment direction vector
    double  cu		= dot(u,u);     // segment length squared

    // test each vertex v[i] for max distance from S
    // compute using the Feb 2001 Algorithm's dist_ofPoint_to_Segment()
    // Note: this works in any dimension (2D, 3D, ...)
    ofPoint  w;
    ofPoint   Pb;                // base of perpendicular from v[i] to S
    float  b, cw, dv2;        // dv2 = distance v[i] to S squared

    for (int i=j+1; i<k; i++){
        // compute distance squared
        w = v[i] - S.P0;
        cw = dot(w,u);
        if ( cw <= 0 ) dv2 = d2(v[i], S.P0);
        else if ( cu <= cw ) dv2 = d2(v[i], S.P1);
        else {
            b = (float)(cw / cu);
            Pb = S.P0 + u*b;
            dv2 = d2(v[i], Pb);
        }
        // test with current max distance squared
        if (dv2 <= maxd2) continue;

        // v[i] is a new max vertex
        maxi = i;
        maxd2 = dv2;
    }
    if (maxd2 > tol2)        // error is worse than the tolerance
    {
        // split the polyline at the farthest vertex from S
        mk[maxi] = 1;      // mark v[maxi] for the simplified polyline
        // recursively simplify the two subpolylines at v[maxi]
        simplifyDP( tol, v, j, maxi, mk );  // polyline v[j] to v[maxi]
        simplifyDP( tol, v, maxi, k, mk );  // polyline v[maxi] to v[k]
    }
    // else the approximation is OK, so ignore intermediate vertices
    return;
}
Exemple #3
0
void Contour::simplify(float tol)
{
  int n = points.size();
  int pv; // misc counters

  // STAGE 1.  Vertex Reduction within tolerance of prior vertex cluster
  int m = 1;// first point always kept
  for (int i = 1, pv = 0; i < n - 1; i++) {
    if (frsm_dist(&points[i], &points[pv]) < tol)
      continue;
    points[m] = points[i];
    pv = m++;
  }
  points[m++] = points[n - 1]; //make sure end is added
  //m vertices in vertex reduced polyline
  points.resize(m);

  // STAGE 2.  Douglas-Peucker polyline simplification
  vector<bool> mk(points.size(), false);
  mk[0] = mk.back() = 1; // mark the first and last vertices
  simplifyDP(tol, points, 0, points.size() - 1, mk);

  // copy marked vertices to the output simplified polyline
  m = 0;
  for (int i = 0; i < points.size(); i++) {
    if (mk[i])
      points[m++] = points[i]; //m<=i;
  }
  //m vertices in simplified polyline
  points.resize(m);

}
Exemple #4
0
void simplify(std::vector<glm::vec3> &_pts, float _tolerance){
    
    if(_pts.size() < 2) return;
    
    int n = _pts.size();
    
    if(n == 0) {
        return;
    }
    
    std::vector<glm::vec3> sV;
    sV.resize(n);
    
    int    i, k, m, pv;            // misc counters
    float  tol2 = _tolerance * _tolerance;       // tolerance squared
    std::vector<glm::vec3> vt;
    std::vector<int> mk;
    vt.resize(n);
    mk.resize(n,0);
    
    
    // STAGE 1.  Vertex Reduction within tolerance of prior vertex cluster
    vt[0] = _pts[0];              // start at the beginning
    for (i=k=1, pv=0; i<n; i++) {
        if (d2(_pts[i], _pts[pv]) < tol2) continue;
        
        vt[k++] = _pts[i];
        pv = i;
    }
    if (pv < n-1) vt[k++] = _pts[n-1];      // finish at the end
    
    // STAGE 2.  Douglas-Peucker polyline simplification
    mk[0] = mk[k-1] = 1;       // mark the first and last vertices
    simplifyDP( _tolerance, &vt[0], 0, k-1, &mk[0] );
    
    // copy marked vertices to the output simplified polyline
    for (i=m=0; i<k; i++) {
        if (mk[i]) sV[m++] = vt[i];
    }
    
    //get rid of the unused points
    if( m < (int)sV.size() ){
        _pts.assign( sV.begin(),sV.begin()+m );
    }else{
        _pts = sV;
    }
}
void ofPolyline::simplify(float tol){

	int n = size();

	vector <ofPoint> sV;
	sV.resize(n);

    int    i, k, m, pv;            // misc counters
    float  tol2 = tol * tol;       // tolerance squared
    vector<ofPoint> vt;
    vector<int> mk;
    vt.resize(n);
	mk.resize(n,0);


    // STAGE 1.  Vertex Reduction within tolerance of prior vertex cluster
    vt[0] = points[0];              // start at the beginning
    for (i=k=1, pv=0; i<n; i++) {
        if (d2(points[i], points[pv]) < tol2) continue;

        vt[k++] = points[i];
        pv = i;
    }
    if (pv < n-1) vt[k++] = points[n-1];      // finish at the end

    // STAGE 2.  Douglas-Peucker polyline simplification
    mk[0] = mk[k-1] = 1;       // mark the first and last vertices
    simplifyDP( tol, &vt[0], 0, k-1, &mk[0] );

    // copy marked vertices to the output simplified polyline
    for (i=m=0; i<k; i++) {
        if (mk[i]) sV[m++] = vt[i];
    }

	//get rid of the unused points
	if( m < (int)sV.size() ){
		points.assign( sV.begin(),sV.begin()+m );
	}else{
		points = sV;
	}

}
//-------------------------------------------------------------------
// needs simplifyDP which is above
static vector <ofPoint> ofSimplifyContour(vector <ofPoint> &V, float tol){
	int n = V.size();

	vector <ofPoint> sV;
	sV.assign(n, ofPoint());

    int    i, k, m, pv;            // misc counters
    float  tol2 = tol * tol;       // tolerance squared
    ofPoint * vt = new ofPoint[n];
	int * mk = new int[n];

	memset(mk, 0, sizeof(int) * n );

    // STAGE 1.  Vertex Reduction within tolerance of prior vertex cluster
    vt[0] = V[0];              // start at the beginning
    for (i=k=1, pv=0; i<n; i++) {
        if (d2(V[i], V[pv]) < tol2) continue;

        vt[k++] = V[i];
        pv = i;
    }
    if (pv < n-1) vt[k++] = V[n-1];      // finish at the end

    // STAGE 2.  Douglas-Peucker polyline simplification
    mk[0] = mk[k-1] = 1;       // mark the first and last vertices
    simplifyDP( tol, vt, 0, k-1, mk );

    // copy marked vertices to the output simplified polyline
    for (i=m=0; i<k; i++) {
        if (mk[i]) sV[m++] = vt[i];
    }

	//get rid of the unused points
	if( m < (int)sV.size() ) sV.erase( sV.begin()+m, sV.end() );

	delete [] vt;
	delete [] mk;

	return sV;
}