From 5e0c885673f67701ad8b48db637e0e42f5282ae4 Mon Sep 17 00:00:00 2001 From: dmatetelki Date: Wed, 24 Jun 2015 12:58:22 +0200 Subject: [PATCH] refactoring MarchingSquares::RunMarchingSquares, merging lines part2, not using direction vectors, but following the vertical/horizontal line till possible. --- lib/qtgraph/marching_squares.cpp | 234 +++++++++++++++++++------------ 1 file changed, 146 insertions(+), 88 deletions(-) diff --git a/lib/qtgraph/marching_squares.cpp b/lib/qtgraph/marching_squares.cpp index 7b2d6da..bb6d34f 100644 --- a/lib/qtgraph/marching_squares.cpp +++ b/lib/qtgraph/marching_squares.cpp @@ -8,9 +8,32 @@ // #include #include +#include namespace { + namespace Color { + enum Code { + FG_RED = 31, + FG_GREEN = 32, + FG_BLUE = 34, + FG_DEFAULT = 39, + BG_RED = 41, + BG_GREEN = 42, + BG_BLUE = 44, + BG_DEFAULT = 49 + }; + class Modifier { + Code code; + public: + Modifier(Code pCode) : code(pCode) {} + friend std::ostream& + operator<<(std::ostream& os, const Modifier& mod) { + return os << "\033[" << mod.code << "m"; + } + }; + } + struct int2 { int x, y; constexpr int2 (int _x, int _y) : x(_x), y(_y) {} @@ -71,37 +94,57 @@ void MarchingSquares::ReadImage(const std::string& filename) std::vector< std::pair > MarchingSquares::RunMarchingSquares() { - constexpr float2 points[8] = { // clockwise, starting in top-left corner - float2(-1, -1 ), // TL 0 - float2(-0.5f, -1 ), // T 1 - float2(0, -1 ), // TR 2 - float2(0, -0.5f), // R 3 - float2(0, 0 ), // BR 4 - float2(-0.5f, 0 ), // B 5 - float2(-1, 0 ), // BL 6 - float2(-1, -0.5f) // L 7 - }; - - constexpr int2 step[16] = { // clockwise, starting in top-left corner - int2(0, 0), // 0x0 - int2(1, 1), // 0x1 - int2(-1, 1), // 0x2 - int2(1, 0), // 0x3 - int2(-1, 1), // 0x4 - int2(0, 1), // 0x5 - int2(0, 0), // 0x6 - int2(0, 0), // 0x7 - int2(1, 1), // 0x8 - int2(0, 0), // 0x9 - int2(0, 1), // 0xa - int2(0, 0), // 0xb - int2(1, 0), // 0xc - int2(0, 0), // 0xd - int2(0, 0), // 0xe - int2(0, 0) // 0xf - }; - - constexpr float2 center(0.5, 0.5); +// constexpr float2 points[8] = { // clockwise, starting in top-left corner +// float2(-1, -1 ), // TL 0 +// float2(-0.5f, -1 ), // T 1 +// float2(0, -1 ), // TR 2 +// float2(0, -0.5f), // R 3 +// float2(0, 0 ), // BR 4 +// float2(-0.5f, 0 ), // B 5 +// float2(-1, 0 ), // BL 6 +// float2(-1, -0.5f) // L 7 +// }; + +// constexpr int2 step[16] = { // clockwise, starting in top-left corner +// int2(0, 0), // 0x0 +// int2(1, 1), // 0x1 +// int2(1, 0), // 0x2 +// int2(1, 0), // 0x3 +// int2(-1, 1), // 0x4 +// int2(0, 1), // 0x5 +// int2(0, 0), // 0x6 +// int2(1, 0), // 0x7 +// int2(1, 0), // 0x8 +// int2(0, 0), // 0x9 +// int2(0, 1), // 0xa +// int2(0, 0), // 0xb +// int2(1, 0), // 0xc +// int2(1, 0), // 0xd +// int2(0, 0), // 0xe +// int2(0, 0) // 0xf +// }; + +// constexpr int next[16] = { +// 0x0, // x0x0 +// 0x0, // x0x1 +// 0x3, // x0x2 +// 0x0, // x0x3 // DC +// 0x0, // x0x4 +// 0x0, // x0x5 +// 0x0, // x0x6 +// 0x3, // x0x7 +// 0xc, // x0x8 +// 0x0, // x0x9 +// 0x0, // x0xa +// 0x0, // x0xb +// 0x0, // x0xc +// 0xc, // x0xd +// 0x0, // x0xe +// 0x0 // x0xf // DC +// }; + +// constexpr float2 center(0.5, 0.5); +// constexpr float2 center(0.0, 0.0); const int number_of_cells = width_*height_; std::vector visited(number_of_cells, false); @@ -113,71 +156,86 @@ MarchingSquares::RunMarchingSquares() { const int mask = getMaskAt(cells_, width_, point); - // these are the marching squares cases - int s = -1, e = -1; - switch (mask) { - case 0x0: /* all free, nothing to do */ break; - - case 0x1: /* TL = TL */ s = 7; e = 1; break; - case 0x2: /* TR = TR */ s = 3; e = 1; break; - case 0x4: /* BL = BL */ s = 5; e = 7; break; - case 0x8: /* BR = BR */ s = 5; e = 3; break; - - case 0x3: /* TLTR = top */ s = 7; e = 3; break; - case 0x5: /* TL BL = left */ s = 1; e = 5; break; - case 0xa: /* TR BR = right */ s = 1; e = 5; break; - case 0xc: /* BLBR = bottom */ s = 7; e = 3; break; - - // two lines - case 0x6: /* TRBL = left desc diagonal */ s = 1 | 5 << 4; e = 3 | 7 << 4; break; - case 0x9: /* TL BR = right asc diagonal */ s = 7 | 3 << 4; e = 1 | 5 << 4; break; - - case 0x7: /* TLTRBL = BR free */ s = 3; e = 5; break; - case 0xb: /* TLTR BR = BL free */ s = 5; e = 7; break; - case 0xd: /* TL BLBR = TR free */ s = 1; e = 3; break; - case 0xe: /* TRBLBR = TL free */ s = 7; e = 1; break; - - case 0xf: /* all blocked, nothing to do */ break; - } - - std::cout << mask << " "; +// // these are the marching squares cases +// int s = -1, e = -1; +// switch (mask) { +// case 0x0: /* all free, nothing to do */ break; +// +// case 0x1: /* TL = TL */ s = 7; e = 1; break; +// case 0x2: /* TR = TR */ s = 3; e = 1; break; +// case 0x4: /* BL = BL */ s = 5; e = 7; break; +// case 0x8: /* BR = BR */ s = 5; e = 3; break; +// +// case 0x3: /* TLTR = top */ s = 7; e = 3; break; +// case 0x5: /* TL BL = left */ s = 1; e = 5; break; +// case 0xa: /* TR BR = right */ s = 1; e = 5; break; +// case 0xc: /* BLBR = bottom */ s = 7; e = 3; break; +// +// // two lines +// case 0x6: /* TRBL = left desc diagonal */ s = 1 | 5 << 4; e = 3 | 7 << 4; break; +// case 0x9: /* TL BR = right asc diagonal */ s = 7 | 3 << 4; e = 1 | 5 << 4; break; +// +// case 0x7: /* TLTRBL = BR free */ s = 3; e = 5; break; +// case 0xb: /* TLTR BR = BL free */ s = 5; e = 7; break; +// case 0xd: /* TL BLBR = TR free */ s = 1; e = 3; break; +// case 0xe: /* TRBLBR = TL free */ s = 7; e = 1; break; +// +// case 0xf: /* all blocked, nothing to do */ break; +// } + + Color::Modifier blue(Color::FG_BLUE); + Color::Modifier def(Color::FG_DEFAULT); + if (mask != 0) + std::cout << std::left << std::setw(3) << mask; + else + std::cout << blue << mask << def << " "; if (visited[point.y*width_ + point.x] == true) continue; - if (s == -1) { - // assert: e == -1 - } + if (mask == 0x0 || mask == 0xf) // empty or full + continue; -// if (mask == 0x7) -// continue; - - else if ((s & 0xf) == s) { - // assert: (e & 0xf) == e -// lines.push_back(std::pair(points[s]+center+point, points[e]+center+point)); - - if (mask == 0x3 || mask == 0x5 || mask == 0xa || mask == 0xc -// || mask == 0x1 || mask == 0x2 || mask == 0x4 || mask == 0x8 - ) { - int2 i = point; - while (true) { - int2 next = i + step[mask]; - if (next.x < width_ && point.y < height_ && getMaskAt(cells_, width_, next) == mask && visited[next.y*width_ + next.x] == false) { - visited[next.y*width_ + next.x] = true; - i = next; - } else + // vertical lines start with an edge + assert(mask != 3); + assert(mask != 12); + assert(mask != 5); + assert(mask != 10); + + if (mask == 0x7 || mask == 0x2 || mask == 0x8 || mask == 0xd || mask == 0x6 || mask == 0x9) { + int2 i = point; + int counter = 0; + while (true) { + int2 n = int2(i.x + 1, i.y); + int next_mask = getMaskAt(cells_, width_, n); + if (n.x < width_ && point.y < height_ && + (next_mask == 0x3 || next_mask == 0xc) && + visited[n.y*width_ + n.x] == false) { + visited[n.y*width_ + n.x] = true; + i = n; + ++counter; + } else break; - } - lines.push_back(std::pair(points[s]+center+point, points[e]+center+i)); } - else - lines.push_back(std::pair(points[s]+center+point, points[e]+center+point)); + lines.push_back(std::pair(float2(point.x, point.y), float2( i.x + 1, i.y))); } - else { - int s1 = s & 0xf, e1 = e & 0xf; - int s2 = s >> 4, e2 = e >> 4; - lines.push_back(std::pair(points[s1]+center+point, points[e1]+center+point)); - lines.push_back(std::pair(points[s2]+center+point, points[e2]+center+point)); + + if (mask == 0x7 || mask == 0xb || mask == 0x4 || mask == 0x8 || mask == 0x6 || mask == 0x9) { + int2 i = point; + int counter = 0; + while (true) { + int2 n = int2(i.x, i.y + 1); + int next_mask = getMaskAt(cells_, width_, n); + if (n.x < width_ && point.y < height_ && + (next_mask == 0xa || next_mask == 0x5) && + visited[n.y*width_ + n.x] == false) { + visited[n.y*width_ + n.x] = true; + i = n; + ++counter; + } else + break; + } + lines.push_back(std::pair(float2(point.x, point.y), float2( i.x, i.y + 1))); } visited[point.y*width_ + point.x] = true;