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

Generated on Wed Jan 16 18:41:28 2008 for QVision by  doxygen 1.5.3