refactoring MarchingSquares::RunMarchingSquares, merging lines part2, not using direction vectors, but following the vertical/horizontal line till possible.

master
dmatetelki 10 years ago
parent 31263b73cc
commit 5e0c885673

@ -8,9 +8,32 @@
// #include <bitset>
#include <iostream>
#include <iomanip>
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<float2, float2> >
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<bool> 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 == 0x7)
// continue;
if (mask == 0x0 || mask == 0xf) // empty or full
continue;
else if ((s & 0xf) == s) {
// assert: (e & 0xf) == e
// lines.push_back(std::pair<float2, float2>(points[s]+center+point, points[e]+center+point));
// vertical lines start with an edge
assert(mask != 3);
assert(mask != 12);
assert(mask != 5);
assert(mask != 10);
if (mask == 0x3 || mask == 0x5 || mask == 0xa || mask == 0xc
// || mask == 0x1 || mask == 0x2 || mask == 0x4 || mask == 0x8
) {
if (mask == 0x7 || mask == 0x2 || mask == 0x8 || mask == 0xd || mask == 0x6 || mask == 0x9) {
int2 i = point;
int counter = 0;
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;
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<float2, float2>(points[s]+center+point, points[e]+center+i));
lines.push_back(std::pair<float2, float2>(float2(point.x, point.y), float2( i.x + 1, i.y)));
}
else
lines.push_back(std::pair<float2, float2>(points[s]+center+point, points[e]+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;
}
else {
int s1 = s & 0xf, e1 = e & 0xf;
int s2 = s >> 4, e2 = e >> 4;
lines.push_back(std::pair<float2, float2>(points[s1]+center+point, points[e1]+center+point));
lines.push_back(std::pair<float2, float2>(points[s2]+center+point, points[e2]+center+point));
lines.push_back(std::pair<float2, float2>(float2(point.x, point.y), float2( i.x, i.y + 1)));
}
visited[point.y*width_ + point.x] = true;

Loading…
Cancel
Save