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 
00264                 inline uInt unify(QPoint p1, QPoint p2)
00265                         {
00266                         Q_ASSERT_X(cols > 0, "QVDisjointSet::unify", "Number of columns equals 0");
00267                         Q_ASSERT_X(rows > 0, "QVDisjointSet::unify", "Number of rows equals 0");
00268                         Q_ASSERT_X(QRect(0,0,cols, rows).contains(p1), "QVDisjointSet::unify", "First QPoint out of image bounds");
00269                         Q_ASSERT_X(QRect(0,0,cols, rows).contains(p2), "QVDisjointSet::unify", "Second QPoint out of image bounds");
00270 
00271                         return unify(INDEX(p1.x(),p1.y()),INDEX(p2.x(),p2.y()));
00272                         }
00273 
00293                 inline uInt unify(uInt c1, uInt r1, uInt c2, uInt r2)
00294                         {
00295                         Q_ASSERT_X(cols > 0, "QVDisjointSet::unify", "Number of columns equals 0");
00296                         Q_ASSERT_X(rows > 0, "QVDisjointSet::unify", "Number of rows equals 0");
00297                         Q_ASSERT_X(QRect(0,0,cols, rows).contains(QPoint(c1, r1)),
00298                                         "QVDisjointSet::unify", "First QPoint out of image bounds");
00299                         Q_ASSERT_X(QRect(0,0,cols, rows).contains(QPoint(c2, r2)),
00300                                         "QVDisjointSet::unify", "Second QPoint out of image bounds");
00301 
00302                         return unify(INDEX(c1,r1),INDEX(c2,r2));
00303                         }
00304 
00309                 inline uInt getSetCardinality(QPoint p1)        { return getSetCardinality(INDEX(p1.x(), p1.y())); }
00310 
00316                 inline uInt getSetCardinality(uInt col, uInt row)       { return getSetCardinality(INDEX(col, row)); }
00317 
00323                 inline uInt find(uInt index)
00324                         {
00325                         Q_ASSERT_X(index < elements, "QVDisjointSet::find", "Index exceeds number of elements");
00326 
00327                         if (parent[index] == index)
00328                                 return index;
00329 
00330                         if (parent[parent[index]] != parent[index])
00331                                 parent[index] = find(parent[index]);
00332 
00333                         return parent[index];
00334                         }
00335 
00345                 uInt unify(uInt index1, uInt index2);
00346                 //uInt unify2(uInt index1, uInt index2);
00347 
00352                 inline uInt getSetCardinality(uInt index)
00353                         {
00354                         Q_ASSERT(count[find(index)] > 0);
00355                         return count[find(index)];
00356                         }
00357 
00361                 inline uInt numberOfSets()      { return sets; }
00362 
00367                 inline uInt index(QPoint p)             { return INDEX(p.x(), p.y()); }
00368 
00374                 inline uInt index(uInt col, uInt row)   { return INDEX(col, row); }
00375 
00376         private:
00377                 uInt elements, sets, cols, rows;
00378                 uInt *parent, *rank, *count;
00379                 
00380                 void makeSet();
00381                 void allocData();
00382                 void freeData();
00383         };
00384 }
00385 #endif

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