src/qvdta/qvdisjointset.h

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 #ifndef QVDISJOINTSET_H
00026 #define QVDISJOINTSET_H
00027 
00028 #include <qvcore/qvimage.h>
00029 
00030 #define INDEX(Col, Row) (Col*rows + Row)
00031 
00032 namespace qvdta
00033 {
00148 class QVDisjointSet
00149         {
00150         public:
00157                 QVDisjointSet(uInt numElements);
00158 
00174                 QVDisjointSet(uInt cols, uInt rows);
00175 
00189                 QVDisjointSet(QVGenericImage &image);
00190 
00191                 ~QVDisjointSet();
00192 
00209                 inline uInt find(QPoint p)
00210                         {
00211                         Q_ASSERT_X(cols > 0, "QVDisjointSet::find", "Number of columns equals 0");
00212                         Q_ASSERT_X(rows > 0, "QVDisjointSet::find", "Number of rows equals 0");
00213 
00215                         Q_ASSERT_X(QRect(0,0,cols, rows).contains(p), "QVDisjointSet::find", "QPoint out of image bounds");
00216                         return find(INDEX(p.x(), p.y()));
00217                         }
00218 
00237                 inline uInt find(uInt col, uInt row)
00238                         {
00239                         Q_ASSERT_X(cols > 0, "QVDisjointSet::find", "Number of columns equals 0");
00240                         Q_ASSERT_X(rows > 0, "QVDisjointSet::find", "Number of rows equals 0");
00241                         Q_ASSERT_X(QRect(0,0,cols, rows).contains(QPoint(col, row)),
00242                                         "QVDisjointSet::find", "QPoint out of image bounds");
00243                         return find(INDEX(col, row));
00244                         }
00245 
00263                 inline uInt unify(QPoint p1, QPoint p2)
00264                         {
00265                         Q_ASSERT_X(cols > 0, "QVDisjointSet::unify", "Number of columns equals 0");
00266                         Q_ASSERT_X(rows > 0, "QVDisjointSet::unify", "Number of rows equals 0");
00267                         Q_ASSERT_X(QRect(0,0,cols, rows).contains(p1), "QVDisjointSet::unify", "First QPoint out of image bounds");
00268                         Q_ASSERT_X(QRect(0,0,cols, rows).contains(p2), "QVDisjointSet::unify", "Second QPoint out of image bounds");
00269 
00270                         return unify(INDEX(p1.x(),p1.y()),INDEX(p2.x(),p2.y()));
00271                         }
00272 
00292                 inline uInt unify(uInt c1, uInt r1, uInt c2, uInt r2)
00293                         {
00294                         Q_ASSERT_X(cols > 0, "QVDisjointSet::unify", "Number of columns equals 0");
00295                         Q_ASSERT_X(rows > 0, "QVDisjointSet::unify", "Number of rows equals 0");
00296                         Q_ASSERT_X(QRect(0,0,cols, rows).contains(QPoint(c1, r1)),
00297                                         "QVDisjointSet::unify", "First QPoint out of image bounds");
00298                         Q_ASSERT_X(QRect(0,0,cols, rows).contains(QPoint(c2, r2)),
00299                                         "QVDisjointSet::unify", "Second QPoint out of image bounds");
00300 
00301                         return unify(INDEX(c1,r1),INDEX(c2,r2));
00302                         }
00303 
00308                 inline uInt getSetCardinality(QPoint p1)        { return getSetCardinality(INDEX(p1.x(), p1.y())); }
00309 
00315                 inline uInt getSetCardinality(uInt col, uInt row)       { return getSetCardinality(INDEX(col, row)); }
00316 
00322                 inline uInt find(uInt index)
00323                         {
00324                         Q_ASSERT_X(index < elements, "QVDisjointSet::find", "Index exceeds number of elements");
00325 
00326                         if (parent[index] != index)
00327                                 parent[index] = find(parent[index]);
00328                         return parent[index];
00329                         }
00330 
00339                 uInt unify(uInt index1, uInt index2);
00340 
00345                 inline uInt getSetCardinality(uInt index)
00346                         {
00347                         Q_ASSERT(count[find(index)] > 0);
00348                         return count[find(index)];
00349                         }
00350 
00354                 inline uInt numberOfSets()      { return sets; }
00355 
00360                 inline uInt index(QPoint p)             { return INDEX(p.x(), p.y()); }
00361 
00367                 inline uInt index(uInt col, uInt row)   { return INDEX(col, row); }
00368 
00369         private:
00370                 uInt elements, sets, cols, rows;
00371                 uInt *parent, *rank, *count;
00372                 
00373                 void makeSet();
00374                 void allocData();
00375                 void freeData();
00376         };
00377 }
00378 #endif

Generated on Fri Dec 7 12:20:59 2007 for QVision by  doxygen 1.5.3