Mercurial > hg > match-vamp
diff src/Finder.cpp @ 75:e1a5f3095ba6 cheap_diagonals
Merge from branch refactors
author | Chris Cannam |
---|---|
date | Wed, 19 Nov 2014 12:13:28 +0000 |
parents | 7aa1ab3db7c9 7e3c1bc0984a |
children | eb3392bf6150 |
line wrap: on
line diff
--- a/src/Finder.cpp Tue Nov 18 10:33:12 2014 +0000 +++ b/src/Finder.cpp Wed Nov 19 12:13:28 2014 +0000 @@ -20,58 +20,26 @@ #include <algorithm> +using namespace std; -Finder::Finder(Matcher *p1, Matcher *p2) +Finder::Finder(Matcher *pm) { - if (!p1->m_firstPM) - std::cerr << "Warning: wrong args in Finder()" << std::endl; - pm1 = p1; - pm2 = p2; - index1 = 0; - index2 = 0; - rowRange = new int[2]; - colRange = new int[2]; - duration1 = -1; - duration2 = -1; + m_m = pm; + m_duration1 = -1; + m_duration2 = -1; } // constructor Finder::~Finder() { - delete[] rowRange; - delete[] colRange; } void Finder::setDurations(int d1, int d2) { - duration1 = d1; - duration2 = d2; + m_duration1 = d1; + m_duration2 = d2; } -bool -Finder::find(int i1, int i2) -{ - if (i1 >= 0) { - index1 = i1; - index2 = i2 - pm1->m_first[i1]; - } - return (i1 >= 0) && (i2 >= pm1->m_first[i1]) && (i2 < pm1->m_last[i1]); -} // find() - -void -Finder::getColRange(int row, int *range) -{ - range[0] = pm1->m_first[row]; - range[1] = pm1->m_last[row]; -} // getColRange() - -void -Finder::getRowRange(int col, int *range) -{ - range[0] = pm2->m_first[col]; - range[1] = pm2->m_last[col]; -} // getRowRange() - Matcher::Advance Finder::getExpandDirection(int row, int col) { @@ -81,40 +49,35 @@ Matcher::Advance Finder::getExpandDirection(int row, int col, bool check) { - double min = getPathCost(row, col); - bestRow = row; - bestCol = col; - getRowRange(col, rowRange); - if (rowRange[1] > row+1) - rowRange[1] = row+1; // don't cheat by looking at future :) - for (int index = rowRange[0]; index < rowRange[1]; index++) { - double tmp = getPathCost(index, col); + double min = m_m->getPathCost(row, col); + + int bestRow = row; + int bestCol = col; + + pair<int, int> rowRange = m_m->getRowRange(col); + if (rowRange.second > row+1) { + rowRange.second = row+1; // don't cheat by looking at future :) + } + for (int index = rowRange.first; index < rowRange.second; index++) { + double tmp = m_m->getPathCost(index, col); if (tmp < min) { min = tmp; bestRow = index; } } - getColRange(row, colRange); - if (colRange[1] > col+1) - colRange[1] = col+1; // don't cheat by looking at future :) - for (int index = colRange[0]; index < colRange[1]; index++) { - double tmp = getPathCost(row, index); + + pair<int, int> colRange = m_m->getColRange(row); + if (colRange.second > col+1) { + colRange.second = col+1; // don't cheat by looking at future :) + } + for (int index = colRange.first; index < colRange.second; index++) { + double tmp = m_m->getPathCost(row, index); if (tmp < min) { min = tmp; bestCol = index; bestRow = row; } } - // System.err.print(" BEST: " + bestRow + " " + bestCol + " " + check); - // System.err.println(" " + pm1->frameCount + " " + pm2->frameCount); - if (check) { - // System.err.println(find(row+1, col) + " " + find(row, col+1)); - if (!find(row, col+1)) { - return Matcher::AdvanceThis; - } else if (!find(row+1, col)) { - return Matcher::AdvanceOther; - } - } if (bestRow == row) { if (bestCol == col) { @@ -128,174 +91,91 @@ return Matcher::AdvanceNone; } -} // getExpandDirection() - -float -Finder::getDistance(int row, int col) -{ - if (find(row, col)) { - return pm1->m_distance[row][col - pm1->m_first[row]]; - } - std::cerr << "getDistance(" << row << "," << col << "): out of bounds" << std::endl; - throw "getDistance index out of bounds"; -} // getDistance()/2 - -void -Finder::setDistance(int row, int col, float b) -{ - if (find(row, col)) { - pm1->m_distance[row][col - pm1->m_first[row]] = b; - return; - } - std::cerr << "setDistance(" << row << "," << col << "," << b << "): out of bounds" << std::endl; - throw "setDistance index out of bounds"; -} // setDistance() - -double -Finder::getPathCost(int row, int col) -{ - if (find(row, col)) // "1" avoids div by 0 below - return pm1->m_bestPathCost[row][col - pm1->m_first[row]] / float(1+row+col); - std::cerr << "getPathCost(" << row << "," << col << "): out of bounds" << std::endl; - throw "getPathCost index out of bounds"; -} // getPathCost() - -double -Finder::getRawPathCost(int row, int col) -{ - if (find(row, col)) - return pm1->m_bestPathCost[row][col - pm1->m_first[row]]; - std::cerr << "getRawPathCost(" << row << "," << col << "): out of bounds" << std::endl; - throw "getRawPathCost index out of bounds"; -} // getRawPathCost() - -void -Finder::setPathCost(int row, int col, double cost) -{ - if (find(row, col)) { - pm1->m_bestPathCost[row][col - pm1->m_first[row]] = cost; - return; - } - std::cerr << "setPathCost(" << row << "," << col << "," << cost << "): out of bounds" << std::endl; - throw "setPathCost index out of bounds"; -} // setPathCost() - -Matcher::Advance -Finder::getAdvance() -{ - return pm1->m_advance[index1][index2]; } void -Finder::setAdvance(Matcher::Advance a) -{ - pm1->m_advance[index1][index2] = a; -} - -float -Finder::getDistance() -{ - return pm1->m_distance[index1][index2]; -} // getDistance()/0 - -void -Finder::setDistance(float b) -{ - pm1->m_distance[index1][index2] = b; -} // setDistance() - -double -Finder::getPathCost() -{ - return pm1->m_bestPathCost[index1][index2]; -} // getPathCost() - -void -Finder::setPathCost(double cost) -{ - pm1->m_bestPathCost[index1][index2] = cost; -} // setPathCost() - -void Finder::recalculatePathCostMatrix(int r1, int c1, int r2, int c2) { float diagonalWeight = sqrtf(2.f); - if (!find(r1,c1)) { - std::cerr << "recalculatePathCostMatrix(" << r1 << "," << c1 << "): out of bounds" << std::endl; - throw "recalculatePathCostMatrix index out of bounds"; + int prevRowStart = 0, prevRowStop = 0; + + for (int r = r1; r <= r2; r++) { + + pair<int, int> colRange = m_m->getColRange(r); + + int rowStart = max(c1, colRange.first); + int rowStop = min(c2 + 1, colRange.second); + + for (int c = rowStart; c < rowStop; c++) { + + float newCost = m_m->getDistance(r, c); + Matcher::Advance dir = Matcher::AdvanceNone; + + if (r > r1) { // not first row + double min = -1; + if ((c > prevRowStart) && (c <= prevRowStop)) { + // diagonal from (r-1,c-1) + min = m_m->getPathCost(r-1, c-1) + newCost * diagonalWeight; + dir = Matcher::AdvanceBoth; + } + if ((c >= prevRowStart) && (c < prevRowStop)) { + // vertical from (r-1,c) + double cost = m_m->getPathCost(r-1, c) + newCost; + if ((min < 0) || (cost < min)) { + min = cost; + dir = Matcher::AdvanceThis; + } + } + if (c > rowStart) { + // horizontal from (r,c-1) + double cost = m_m->getPathCost(r, c-1) + newCost; + if ((min < 0) || (cost < min)) { + min = cost; + dir = Matcher::AdvanceOther; + } + } + + m_m->setPathCost(r, c, dir, min); + + } else if (c > rowStart) { // first row + // horizontal from (r,c-1) + m_m->setPathCost(r, c, Matcher::AdvanceOther, + m_m->getPathCost(r, c-1) + newCost); + } + } + + prevRowStart = rowStart; + prevRowStop = rowStop; } - int thisRowStart, c; - int prevRowStart = 0, prevRowStop = 0; - for (int r = r1; r <= r2; r++) { - thisRowStart = pm1->m_first[r]; - if (thisRowStart < c1) - thisRowStart = c1; - for (c = thisRowStart; c <= c2; c++) { - if (find(r,c)) { - int i2 = index2; - float newCost = pm1->m_distance[r][i2]; - Matcher::Advance dir = Matcher::AdvanceNone; - if (r > r1) { // not first row - double min = -1; - if ((c > prevRowStart) && (c <= prevRowStop)) { - // diagonal from (r-1,c-1) - min = pm1->m_bestPathCost[r-1][c-pm1->m_first[r-1]-1] + - newCost * diagonalWeight; - dir = Matcher::AdvanceBoth; - } - if ((c >= prevRowStart) && (c < prevRowStop)) { - // vertical from (r-1,c) - double cost = pm1->m_bestPathCost[r-1][c-pm1->m_first[r-1]] + - newCost; - if ((min == -1) || (cost < min)) { - min = cost; - dir = Matcher::AdvanceThis; - } - } - if (c > thisRowStart) { - // horizontal from (r,c-1) - double cost =pm1->m_bestPathCost[r][i2-1]+newCost; - if ((min == -1) || (cost < min)) { - min = cost; - dir = Matcher::AdvanceOther; - } - } - pm1->m_bestPathCost[r][i2] = min; - } else if (c > thisRowStart) { // first row - // horizontal from (r,c-1) - pm1->m_bestPathCost[r][i2] = pm1->m_bestPathCost[r][i2-1] + - newCost; - dir = Matcher::AdvanceOther; - } - pm1->m_advance[r][i2] = dir; - } else - break; // end of row - } - prevRowStart = thisRowStart; - prevRowStop = c; - } -} // recalculatePathCostMatrix() +} int Finder::retrievePath(bool smooth, vector<int> &pathx, vector<int> &pathy) { - int ex = pm2->getFrameCount() - 1; - int ey = pm1->getFrameCount() - 1; + pathx.clear(); + pathy.clear(); + + int ex = m_m->getOtherFrameCount() - 1; + int ey = m_m->getFrameCount() - 1; + + if (ex < 0 || ey < 0) { + return 0; + } int x = ex; int y = ey; // cerr << "before: x = " << x << ", y = " << y << endl; - if (duration2 > 0 && duration2 < pm2->getFrameCount()) { - x = duration2 - 1; + if (m_duration2 > 0 && m_duration2 < m_m->getOtherFrameCount()) { + x = m_duration2 - 1; } - if (duration1 > 0 && duration1 < pm1->getFrameCount()) { - y = duration1 - 1; + if (m_duration1 > 0 && m_duration1 < m_m->getFrameCount()) { + y = m_duration1 - 1; } - if (!find(y, x)) { + if (!m_m->isAvailable(y, x)) { // Path did not pass through the expected end point -- // probably means the pieces are substantially different in // the later bits. Reset the expected end point to the end of @@ -307,34 +187,31 @@ recalculatePathCostMatrix(0, 0, y, x); - pathx.clear(); - pathy.clear(); - // cerr << "start: x = " << x << ", y = " << y << endl; - while (find(y, x) && ((x > 0) || (y > 0))) { + while (m_m->isAvailable(y, x) && (x > 0 || y > 0)) { // cerr << "x = " << x << ", y = " << y; pathx.push_back(x); pathy.push_back(y); - switch (getAdvance()) { + switch (m_m->getAdvance(y, x)) { case Matcher::AdvanceThis: -// cerr << ", going down (dist = " << (int)getDistance() << ")" << endl; +// cerr << ", going down (dist = " << getDistance() << ")" << endl; y--; break; case Matcher::AdvanceOther: -// cerr << ", going left (dist = " << (int)getDistance() << ")" << endl; +// cerr << ", going left (dist = " << getDistance() << ")" << endl; x--; break; case Matcher::AdvanceBoth: -// cerr << ", going diag (dist = " << (int)getDistance() << ")" << endl; +// cerr << ", going diag (dist = " << getDistance() << ")" << endl; x--; y--; break; case Matcher::AdvanceNone: // this would indicate a bug, but we wouldn't want to hang -// cerr << "WARNING: Neither matcher advanced in path backtrack at (" << x << "," << y << ")" << endl; + cerr << "WARNING: Neither matcher advanced in path backtrack at (" << x << "," << y << ")" << endl; if (x > y) { x--; } else { @@ -344,8 +221,13 @@ } } - std::reverse(pathx.begin(), pathx.end()); - std::reverse(pathy.begin(), pathy.end()); + if (x > 0 || y > 0) { + cerr << "WARNING: Ran out of available path at (" << y << "," << x + << ")!" << endl; + } + + reverse(pathx.begin(), pathx.end()); + reverse(pathy.begin(), pathy.end()); if (smooth) { int smoothedLen = Path().smooth(pathx, pathy, pathx.size());