src/qvdta/qvpolyline.cpp

Go to the documentation of this file.
00001 /*
00002  *      Copyright (C) 2007. PARP Research Group.
00003  *      <http://perception.inf.um.es>
00004  *      University of Murcia, Spain.
00005  *
00006  *      This file is part of the QVision library.
00007  *
00008  *      QVision is free software: you can redistribute it and/or modify
00009  *      it under the terms of the GNU Lesser General Public License as
00010  *      published by the Free Software Foundation, version 3 of the License.
00011  *
00012  *      QVision is distributed in the hope that it will be useful,
00013  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  *      GNU Lesser General Public License for more details.
00016  *
00017  *      You should have received a copy of the GNU Lesser General Public
00018  *      License along with QVision. If not, see <http://www.gnu.org/licenses/>.
00019  */
00020 
00024 
00025 #include <qvdta/qvpolyline.h>
00026 
00027 #define CONST_PI        ((double)3.14159)
00028 #define SIGN(X)         (((X)>=0)?1:-1)
00029 
00031 // QVPolylines
00032 
00033 // IPE
00034 #define xA(Index) (coorX[previous[Index]])
00035 #define yA(Index) (coorY[previous[Index]])
00036 #define xB(Index) (coorX[Index])
00037 #define yB(Index) (coorY[Index])
00038 #define xC(Index) (coorX[next[Index]])
00039 #define yC(Index) (coorY[next[Index]])
00040 #define ABS(X)  (((X)>=0)?(X):-(X))
00041 #define TRIANGLE_AREA(I) ABS(xA(I)*yC(I) - xA(I)*yB(I) + xB(I)*yA(I) - xB(I)*yC(I) + xC(I)*yB(I) - xC(I)*yA(I))
00042 
00043 void IterativePointElimination(const QVPolyline &polyline, QVPolyline &result, const double minAreaDiv2)
00044         {
00045         // Actually, TRIANGLE_AREA does computes the double of the area of the triangle. We double the parameter value
00046         // to correctly adjust it.
00047         const uInt polylineSize = polyline.size(), minArea = minAreaDiv2 * 2;
00048 
00049         if (polylineSize < 3) return;
00050 
00051         // We create a static linked list of points with arrays previous, next, coorX, coorY,
00052         // from the polyline.   
00053         uInt    *previous = new uInt[polylineSize],
00054                 *next = new uInt[polylineSize],
00055                 *valid = new uInt[polylineSize],
00056                 *area = new uInt[polylineSize],
00057                 discartablePoints = 0,
00058                 validPoints = polylineSize;
00059 
00060         int     *coorX = new int[polylineSize],
00061                 *coorY = new int[polylineSize];
00062 
00063         for (uInt i=0; i< polylineSize; i++)
00064                 {
00065                 previous[i] = i-1;
00066                 next[i] = i+1;
00067                 coorX[i] = polyline.at(i).x();
00068                 coorY[i] = polyline.at(i).y();
00069                 }
00070 
00071         previous[0] = polylineSize-1;
00072         next[polylineSize-1] = 0;
00073 
00074         // Create valid index and area initialization
00075         for (uInt i=0; i < polylineSize; i++)
00076                 {
00077                 valid[i] = true;
00078                 area[i] = TRIANGLE_AREA(i);
00079                 }
00080 
00081         // This is where points are actually deleted.
00082         // Well, not deleted, but are marked as not valid,
00083         // and latter when adding points to result
00084         // QVPolyline, not valid points will not be added.
00085         uInt index = 0, lastIndex = previous[index];
00086         bool cond = true;
00087 
00088         while(cond && validPoints > 3)
00089                 {
00090                 Q_ASSERT(valid[index]);
00091                 Q_ASSERT(valid[next[index]]);
00092                 Q_ASSERT(valid[previous[index]]);
00093                 if (area[index] < minArea)
00094                         {
00095                         // we eliminate the point from the set
00096                         valid[index] = false;
00097                         next[previous[index]] = next[index];
00098                         previous[next[index]] = previous[index];
00099                         lastIndex = previous[index];
00100                         validPoints--;
00101 
00102                         // step and actualize contiguous points areas
00103                         index = next[index];
00104                         area[index] = TRIANGLE_AREA(index);
00105                         area[previous[index]] = TRIANGLE_AREA(previous[index]);
00106                         }
00107                 else    {
00108                         // end condition: a whole turn around the linked list with no
00109                         // eliminations.
00110                         if (index == lastIndex)
00111                                 cond = false;
00112 
00113                         // step
00114                         index = next[index];
00115                         }
00116                 }
00117 
00118         // After IPE, if we have a contour of 3 points, return if the triangle
00119         // has less area than minimum.
00120         if (validPoints == 3)
00121                 {
00122                 Q_ASSERT(valid[index]);
00123                 Q_ASSERT(area[index] == area[next[index]]);
00124                 Q_ASSERT(area[index] == area[previous[index]]);
00125                 Q_ASSERT(index == previous[previous[index]]);
00126 
00127                 if (area[index] < minArea)
00128                         return;
00129                 }
00130 
00131         // Store the resulting points in result polyline.
00132         for (uInt n=0; n< polylineSize; n++)
00133                 if (valid[n])
00134                         result.append(polyline.at(n));
00135         result.closed = polyline.closed;
00136         result.direction = polyline.direction;
00137 
00138         delete previous;
00139         delete next;
00140         delete valid;
00141         delete area;
00142         delete coorX;
00143         delete coorY;
00144         }
00145 
00146 // Draw
00147 QVPolyline::QVPolyline(): QList<QPoint>(),
00148         closed(false), direction(false)//, dir(0)
00149         {
00150         qDebug() << "QVPolyline()";
00151         qDebug() << "QVPolyline() <~ return";
00152         };
00153 
00154 QVPolyline::QVPolyline(const QVPolyline &polyline): QList<QPoint>(polyline),
00155         closed(polyline.closed), direction(polyline.direction)//, dir(polyline.dir)
00156         {
00157         qDebug() << "QVPolyline(const QVPolyline &)";
00158         qDebug() << "QVPolyline(const QVPolyline &) <~ return";
00159         };
00160 
00161 QPoint  linesIntersection(QPoint a, QPoint b, QPoint c, QPoint d)
00162         // gets the intersection point for lines ab and cd
00163         {
00164         double x1 = a.rx(), x2 = b.rx(), x3 = c.rx(), x4 = d.rx();
00165         double y1 = a.ry(), y2 = b.ry(), y3 = c.ry(), y4 = d.ry();
00166 
00167         double denominador = (y4 - y3)*(x2 - x1) - (x4 - x3)*(y2 - y1);
00168         if (denominador == 0)
00169                 return QPoint( (int)(b.rx() + c.rx())/2, (int)(b.ry() + c.ry())/2 );
00170 
00171         double  ua = (x4 - x3)*(y1 - y3) - (y4 - y3)*(x1 - x3),
00172                 ub = (x2 - x1)*(y1 - y3) - (y2 - y1)*(x1 - x3);
00173 
00174         QPoint p = QPoint(
00175                         (int) (x1 + ua*(x2 - x1) / denominador),
00176                         (int) (y1 + ub*(y2 - y1) / denominador)
00177                         );
00178         return p;
00179         }
00180 
00182 
00183 void drawPoints(const QList<QPoint> &hotPoints, QVImage<uChar,3> &dest)
00184         {
00185         QListIterator<QPoint> iterator(hotPoints);
00186         uChar pixel[3] = { 255,0,0 };
00187 
00188         while(iterator.hasNext())
00189                 {
00190                 QPoint p = iterator.next();
00191                 QVPolyline rectangle = QVPolyline::rectangle(p.x()-2, p.y()-2, p.x()+2, p.y()+2);
00192                 draw(dest, rectangle, pixel,true,true);
00193                 }
00194         }
00195 
00196 void drawPoints(const QList<QPoint> &hotPoints, QVImage<uChar> &dest)
00197         {
00198         QListIterator<QPoint> iterator(hotPoints);
00199         while(iterator.hasNext())
00200                 {
00201                 QPoint p = iterator.next();
00202                 QVPolyline rectangle = QVPolyline::rectangle(p.x()-2, p.y()-2, p.x()+2, p.y()+2);
00203                 draw(dest, rectangle, 255,true,true);
00204                 }
00205         }
00206 
00207 
00208 void draw(QVImage<uChar> &image, const QVPolyline &polyline, const uChar constant, bool linked, bool safe)
00209         {
00210         Q_ASSERT_X(polyline.size() > 0, "drawPolyline()", "polyline size equals zero");
00211 
00212         QListIterator<QPoint> iterator(polyline);
00213         QRect roi = image.getROI();
00214 
00215         QPoint previous;
00216 
00217         if (linked)
00218                 previous = iterator.next();
00219 
00220         QVIMAGE_INIT_WRITE(uChar,image);
00221         while (iterator.hasNext())
00222                 {
00223                 QPoint actual = iterator.next();
00224                 int x = actual.x(), y = actual.y();
00225                 if (!linked && !safe)
00226                         QVIMAGE_PIXEL(image, x, y,0) = constant;
00227                 else if (linked)
00228                         {
00229                         QVPolyline line = QVPolyline::line(x, y, previous.rx(), previous.ry());
00230                         draw(image, line, constant, false, safe);
00231                         previous = actual;
00232                         }
00233                 else if (roi.contains(x, y))
00234                         QVIMAGE_PIXEL(image, x, y,0) = constant;
00235                 }
00236         }
00237 
00238 void draw(QVImage<uChar,3> &image, const QVPolyline &polyline, const uChar constant[3], bool linked, bool safe)
00239         {
00240         Q_ASSERT_X(polyline.size() > 0, "drawPolyline()", "polyline size equals zero");
00241         //if (polyline.size() == 0) return;
00242 
00243         QListIterator<QPoint> iterator(polyline);
00244         QRect roi = image.getROI();
00245 
00246         QPoint previous;
00247 
00248         if (linked)
00249                 previous = iterator.next();
00250 
00251         QVIMAGE_INIT_WRITE(uChar,image);
00252         while (iterator.hasNext())
00253                 {
00254                 QPoint actual = iterator.next();
00255                 int x = actual.x(), y = actual.y();
00256                 if (!linked && !safe)
00257                         {
00258                         QVIMAGE_PIXEL(image, x, y,0) = constant[0];
00259                         QVIMAGE_PIXEL(image, x, y,1) = constant[1];
00260                         QVIMAGE_PIXEL(image, x, y,2) = constant[2];
00261                         //image(actual.rx(), actual.ry(),0) = constant[0];
00262                         //image(actual.rx(), actual.ry(),1) = constant[1];
00263                         //image(actual.rx(), actual.ry(),2) = constant[2];
00264                         }
00265                 else if (linked)
00266                         {
00267                         QVPolyline line = QVPolyline::line(actual.rx(), actual.ry(), previous.rx(), previous.ry());
00268                         draw(image, line, constant, false, safe);
00269                         previous = actual;
00270                         }
00271                 else if (roi.contains(actual.rx(), actual.ry()))
00272                         {
00273                         QVIMAGE_PIXEL(image, x, y,0) = constant[0];
00274                         QVIMAGE_PIXEL(image, x, y,1) = constant[1];
00275                         QVIMAGE_PIXEL(image, x, y,2) = constant[2];
00276                         /*image(actual.rx(), actual.ry(),0) = constant[0];
00277                         image(actual.rx(), actual.ry(),1) = constant[1];
00278                         image(actual.rx(), actual.ry(),2) = constant[2];*/
00279                         }
00280                 }
00281         }
00282 
00283 
00284 void draw(QVImage<uChar> &img, const QList< QVPolyline > &polylineList, const uChar constant, bool linked, bool safe)
00285         {
00286         QListIterator<QVPolyline> iterator(polylineList);
00287         while (iterator.hasNext())
00288                 draw(img, iterator.next(), constant, linked, safe);
00289         }
00290 
00291 void draw(QVImage<uChar,3> &img,const QList< QVPolyline > &polylineList, const uChar constant[3],bool linked,bool safe)
00292         {
00293         QListIterator<QVPolyline> iterator(polylineList);
00294         while (iterator.hasNext())
00295                 draw(img, iterator.next(), constant, linked, safe);
00296         }
00297 
00298 
00299 QVPolyline QVPolyline::ellipse(uInt n, float x, float y, float maxRadio, float minRadio, float ang)
00300         {
00301         QVPolyline ellipse;
00302         float w = 2*CONST_PI/(n-1);
00303         float maxArg = (maxRadio+minRadio)/2;
00304         float minArg = (maxRadio-minRadio)/2;
00305 
00306         for (uInt t = 0; t < n; t++)
00307                 ellipse.append(QPoint ( (uInt) (x + maxArg*cos(ang+w*t) + minArg*cos(ang-w*t)),
00308                                                 (uInt) (y + maxArg*sin(ang+w*t) + minArg*sin(ang-w*t))
00309                                                 ));
00310         return ellipse;
00311         }
00312 
00313 QVPolyline QVPolyline::rectangle(int x1, int y1, int x2, int y2)
00314         {
00315         QVPolyline rectangle;
00316         rectangle.append(QPoint( x1, y1 ));
00317         rectangle.append(QPoint( x1, y2 ));
00318         rectangle.append(QPoint( x2, y2 ));
00319         rectangle.append(QPoint( x2, y1 ));
00320         rectangle.append(QPoint( x1, y1 ));
00321         return rectangle;
00322         }
00323 
00324 QVPolyline QVPolyline::line(int x1, int y1, int x2, int y2)
00325         {
00326         QVPolyline line;
00327 
00328         line.append(QPoint( x1, y1 ));
00329 
00330         if (x1 == x2 && y1 == y2)
00331                 return line;
00332 
00333         int i,dx,dy,sdx,sdy,dxabs,dyabs,x,y,px,py;
00334         
00335         dx=x2-x1;      // the horizontal distance of the line
00336         dy=y2-y1;      // the vertical distance of the line
00337         dxabs=abs(dx);
00338         dyabs=abs(dy);
00339         sdx=SIGN(dx);
00340         sdy=SIGN(dy);
00341         x=dyabs>>1;
00342         y=dxabs>>1;
00343         px=x1;
00344         py=y1;
00345         
00346         if (dxabs>=dyabs) // the line is more horizontal than vertical
00347                 for(i=0;i<dxabs;i++)
00348                         {
00349                         y+=dyabs;
00350                         if (y>=dxabs)
00351                                 {
00352                                 y-=dxabs;
00353                                 py+=sdy;
00354                                 }
00355                         px+=sdx;
00356                         line.append(QPoint( px, py ));
00357                         }
00358         else    // the line is more vertical than horizontal
00359                 for(i=0;i<dyabs;i++)
00360                         {
00361                         x+=dxabs;
00362                         if (x>=dyabs)
00363                                 {
00364                                 x-=dyabs;
00365                                 px+=sdx;
00366                                 }
00367                         py+=sdy;
00368                         line.append(QPoint( px, py ));
00369                         }
00370 
00371         return line;
00372         }
00373 
00374 /*void joinExtremes(QVPolyline &main, QVPolyline &second)
00375         {
00376         QPoint a1 = main.takeLast(), a2 = main.last(), b1 = second.at(0), b2 = second.at(1);
00377 
00378         main.append(linesIntersection(a1,a2, b1,b2));
00379 
00380         for (int i = 1; i< second.size(); i++)
00381                 main.append(second.at(i));
00382         }
00383 
00384 double dist2(QPoint p1, QPoint p2)
00385         { return (p1.x() - p2.x())*(p1.x() - p2.x()) + (p1.y() - p2.y())*(p1.y() - p2.y()); }
00386 
00387 template <typename T>QList<T> & reverse(QList<T> &p)
00388         {
00389         for (int i = 0; i< p.size()/2; i++)
00390                 p.swap(i, p.size()-i-1);
00391         return p;
00392         }
00393 
00394 QList<QVPolyline> * compactPolylines(const QList<QVPolyline> &polylineList, double maxDist)
00395         {
00396         //qDebug() << "compactPolylines()";
00397         uInt n = polylineList.size();
00398         //qDebug() << "compactPolylines(): size"<<n;
00399         //if (n < 2) return new QList<QVPolyline>(polylineList);
00400 
00401         bool * segmentUsed = new bool[n];
00402         QList<QVPolyline> * result = new QList<QVPolyline>();
00403 
00404         for (uInt i=0; i<n; i++)
00405                 segmentUsed[i] = false;
00406 
00407         for (uInt i=0; i<n-1; i++)
00408                 {
00409                 //qDebug() << "compactPolylines(): segmento" << i << segmentUsed[i];
00410                 if (segmentUsed[i]) continue;
00411                 QVPolyline actual = polylineList.at(i);
00412                 if (actual.size() < 2) continue;
00413 
00414                 for (uInt j= i+1; j<n; j++)
00415                         {
00416                         if (segmentUsed[j]) continue;
00417                         QVPolyline next = polylineList.at(j);
00418                         if (next.size() < 2) continue;
00419 
00420                         if (dist2(actual.back(), next.front()) < maxDist)
00421                                 { append(actual, next); segmentUsed[j] = true; }
00422 
00423                         else if (dist2(actual.back(), next.back()) < maxDist)
00424                                 { reverse(next); append(actual, next); segmentUsed[j] = true; }
00425 
00426                         else if (dist2(actual.front(), next.front()) < maxDist)
00427                                 { reverse(actual); append(actual, next); segmentUsed[j] = true; }
00428 
00429                         else if (dist2(actual.front(), next.back()) < maxDist)
00430                                 { reverse(actual); reverse(next); append(actual, next); segmentUsed[j] = true; }
00431                         }
00432 
00433                 if ( (actual.size() > 3) && (dist2(actual.back(), actual.front()) < maxDist) )
00434                         {
00435                         QPoint a1 = actual.takeLast(), a2 = actual.last(), b1 = actual.takeFirst(), b2 = actual.front();
00436                         QPoint p = linesIntersection(a1,a2, b1,b2);
00437                         actual.push_back(p);
00438                         actual.push_front(p);
00439                         }
00440 
00441                 result->append(actual);
00442                 }
00443 
00444         if (!segmentUsed[n-1])
00445                 result->append(polylineList.back());
00446 
00447         delete [] segmentUsed;
00448 
00449         return result;
00450         }*/
00451 
00452 /*void qvEllipse(QVPolyline &ellipse, uInt n, float x, float y, float maxRadio, float minRadio, float ang)
00453         {
00454         float w = 2*CONST_PI/(n-1);
00455         float maxArg = (maxRadio+minRadio)/2;
00456         float minArg = (maxRadio-minRadio)/2;
00457 
00458         for (uInt t = 0; t < n; t++)
00459                 ellipse.append(QPoint ( (uInt) (x + maxArg*cos(ang+w*t) + minArg*cos(ang-w*t)),
00460                                                 (uInt) (y + maxArg*sin(ang+w*t) + minArg*sin(ang-w*t))
00461                                                 ));
00462         }
00463 
00464 void qvRectangle(QVPolyline &rectangle, int x1, int y1, int x2, int y2)
00465         {
00466         rectangle.append(QPoint( x1, y1 ));
00467         rectangle.append(QPoint( x1, y2 ));
00468         rectangle.append(QPoint( x2, y2 ));
00469         rectangle.append(QPoint( x2, y1 ));
00470         rectangle.append(QPoint( x1, y1 ));
00471         }
00472 
00473 void qvLine(QVPolyline &line, int x1, int y1, int x2, int y2)
00474         {
00475         line.append(QPoint( x1, y1 ));
00476         if (x1 == x2 && y1 == y2)
00477                 return;
00478 
00479         int i,dx,dy,sdx,sdy,dxabs,dyabs,x,y,px,py;
00480         
00481         dx=x2-x1;
00482         dy=y2-y1;
00483         dxabs=abs(dx);
00484         dyabs=abs(dy);
00485         sdx=SIGN(dx);
00486         sdy=SIGN(dy);
00487         x=dyabs>>1;
00488         y=dxabs>>1;
00489         px=x1;
00490         py=y1;
00491         
00492         if (dxabs>=dyabs)
00493                 for(i=0;i<dxabs;i++)
00494                         {
00495                         y+=dyabs;
00496                         if (y>=dxabs)
00497                                 {
00498                                 y-=dxabs;
00499                                 py+=sdy;
00500                                 }
00501                         px+=sdx;
00502                         line.append(QPoint( px, py ));
00503                         }
00504         else
00505                 for(i=0;i<dyabs;i++)
00506                         {
00507                         x+=dxabs;
00508                         if (x>=dyabs)
00509                                 {
00510                                 x-=dyabs;
00511                                 px+=sdx;
00512                                 }
00513                         py+=sdy;
00514                         line.append(QPoint( px, py ));
00515                         }
00516         }*/
00517         
00518 
00520 #define dist2(A,B)      (((A).rx() -(B).rx())*((A).rx() -(B).rx()) + ((A).ry() -(B).ry())*((A).ry() -(B).ry()))
00521 #define dot(A,B)        ( (A).rx()*(B).rx() + (A).ry()*(B).ry() )
00522 
00523 // simplifyDP():
00524 //  This is the Douglas-Peucker recursive simplification routine
00525 //  It just marks vertices that are part of the simplified polyline
00526 //  for approximating the polyline subchain v[j] to v[k].
00527 //    Input:  tol = approximation tolerance
00528 //            v[] = polyline array of vertex points 
00529 //            j,k = indices for the subchain v[j] to v[k]
00530 //    Output: mk[] = array of markers matching vertex array v[]
00531 /*void simplifyDP( float tol, QPoint* v, int j, int k, int* mk )
00532         {
00533         if (k <= j+1) // there is nothing to simplify
00534                 return;
00535 
00536         // check for adequate approximation by segment S from v[j] to v[k]
00537         int     maxi = j;          // index of vertex farthest from S
00538         float   maxd2 = 0;         // distance squared of farthest vertex
00539 
00540         QPoint S_P0 = v[j],
00541                 S_P1 = v[k];
00542 
00543         QPoint u = QPoint( S_P1.rx() - S_P0.rx(), S_P1.ry() - S_P0.ry() );
00544         double  cu = dot(u,u);     // segment length squared
00545         
00546         // test each vertex v[i] for max distance from S
00547         // compute using the Feb 2001 Algorithm's dist_Point_to_Segment()
00548         // Note: this works in any dimension (2D, 3D, ...)
00549         QPoint  w;   // vector
00550         QPoint   Pb;                // base of perpendicular from v[i] to S
00551         double  b, cw, dv2;        // dv2 = distance v[i] to S squared
00552         
00553         for (int i=j+1; i<k; i++)
00554                 {
00555                 // compute distance squared
00556                 w = QPoint( v[i].rx() - S_P0.rx(), v[i].ry() - S_P0.ry() );
00557                 cw = dot(w,u);
00558                 if ( cw <= 0 )   // if perp line doesnt fall on u, it calculates the dist2 to the nearest vertex
00559                         dv2 = dist2(v[i], S_P0);
00560                 else if ( cu <= cw )
00561                         dv2 = dist2(v[i], S_P1);
00562                 else
00563                         {
00564                         // if perp line does fall on u, it calculates the height^2 of the triangle
00565                         b = cw / cu;
00566                         Pb = QPoint( S_P0.rx() + (int) (b * u.rx()), S_P0.ry() + (int)(b*u.ry()) );
00567                         dv2 = dist2(v[i], Pb);
00568                         }
00569                 // test with current max distance squared
00570                 if (dv2 <= maxd2) 
00571                         continue;
00572                 // v[i] is a new max vertex
00573                 maxi = i;
00574                 maxd2 = dv2;
00575                 }
00576         if (maxd2 > tol * tol)        // error is worse than the tolerance
00577                 {
00578                 // split the polyline at the farthest vertex from S
00579                 mk[maxi] = 1;                           // mark v[maxi] for the simplified polyline
00580                                                         // recursively simplify the two subpolylines at v[maxi]
00581                 simplifyDP( tol, v, j, maxi, mk );      // polyline v[j] to v[maxi]
00582                 simplifyDP( tol, v, maxi, k, mk );      // polyline v[maxi] to v[k]
00583                 }
00584         // else the approximation is OK, so ignore intermediate vertices
00585         return;
00586         }*/
00587 
00588 // poly_simplify():
00589 //    Input:  tol = approximation tolerance
00590 //            V[] = polyline array of vertex points 
00591 //            n   = the number of points in V[]
00592 //    Output: sV[]= simplified polyline vertices (max is n)
00593 //    Return: m   = the number of points in sV[]
00594 /*QVPolyline IPE2( float tol, const QVPolyline &V )
00595         {
00596         int n=V.size();
00597         if (n == 0) return V;
00598 
00599         QVPolyline sV;
00600 
00601         QPoint* vt = new QPoint[n];      // vertex buffer
00602         int*   mk = new int[n];         // marker buffer
00603         
00604         // STAGE 1.  Vertex Reduction within tolerance of prior vertex cluster
00605         vt[0] = V.at(0);              // start at the beginning
00606 
00607         int i,k,pv;
00608         for (i=k=1, pv=0; i<n; i++)
00609                 {
00611                 //if (dist2(V.at(i), V.at(pv)) < tol*tol)
00612                 //      continue;
00613                 vt[k++] = V.at(i);
00614                 pv = i;
00615                 }
00616         if (pv < n-1)
00617         vt[k++] = V.at(n-1);      // finish at the end
00618         
00619         // STAGE 2.  Douglas-Peucker polyline simplification
00620         for(int i=0; i<n; ++i)
00621                 mk[i]=0;
00622         mk[0] = mk[k-1] = 1;       // mark the first and last vertices
00623         simplifyDP( tol, vt, 0, k-1, mk );
00624         
00625         // copy marked vertices to the output simplified polyline
00626         for (int i=0; i<k; i++)
00627                 {
00628                 if (mk[i])
00629                         sV.append(vt[i]);
00630                         //sV.push_back(vt[i]);
00631                 }
00632         delete vt;
00633         delete mk;
00634         return sV;         // simplyfied polyline
00635         }*/
00636 

Generated on Fri Feb 22 18:26:55 2008 for QVision by  doxygen 1.5.3