diff --git a/src/experimental/_impl/_mz_hamiltonian_impl.scad b/src/experimental/_impl/_mz_hamiltonian_impl.scad new file mode 100644 index 00000000..cc6d3355 --- /dev/null +++ b/src/experimental/_impl/_mz_hamiltonian_impl.scad @@ -0,0 +1,54 @@ +use ; + +function _mz_hamiltonian_upper(x, y) = + let( + nx = (x - 1) * 2, + ny = (y - 1) * 2 + ) + [[nx, ny + 2], [nx + 1, ny + 2], [nx + 2, ny + 2]]; + +function _mz_hamiltonian_right(x, y) = + let( + nx = (x - 1) * 2, + ny = (y - 1) * 2 + ) + [[nx + 2, ny + 2], [nx + 2, ny + 1], [nx + 2, ny]]; + +function _mz_hamiltonian_upper_right(x, y) = + let( + nx = (x - 1) * 2, + ny = (y - 1) * 2 + ) + [[nx, ny + 2], [nx + 1, ny + 2], [nx + 2, ny + 2], [nx + 2, ny + 1], [nx + 2, ny]]; + +function _mz_hamiltonian_corner_value(dots, x, y) = + let( + c1 = has(dots, [x, y]) ? 1 : 0, + c2 = has(dots, [x, y + 1]) ? 2 : 0, + c3 = has(dots, [x + 1, y + 1]) ? 4 : 0, + c4 = has(dots, [x + 1, y]) ? 8 : 0 + ) + c1 + c2 + c3 + c4; + +function _mz_hamiltonian_dir(cr_value) = + lookup(cr_value, [ + [4, 0], [12, 0], [13, 0], // UP + [1, 1], [3, 1], [7, 1], // DOWN + [2, 2], [6, 2], [14, 2], // LEFT + [8, 3], [9, 3], [11, 3] // RIGHT + ]); + +function _mz_hamiltonian_travel(dot_pts, p, leng, i = 0) = + i == leng ? [] : + let( + dir_i = _mz_hamiltonian_dir(_mz_hamiltonian_corner_value(dot_pts, p[0], p[1])), + nxt_p = p + [ + [0, 1], // UP + [0, -1], // DOWN + [-1, 0], // LEFT + [1, 0] // RIGHT + ][dir_i] + ) + concat( + [p], _mz_hamiltonian_travel(dot_pts, nxt_p, leng, i + 1) + ); diff --git a/src/experimental/mz_hamiltonian.scad b/src/experimental/mz_hamiltonian.scad new file mode 100644 index 00000000..5004e4ad --- /dev/null +++ b/src/experimental/mz_hamiltonian.scad @@ -0,0 +1,31 @@ +use ; +use ; +use ; +use ; + +function mz_hamiltonian(start, rows, columns) = + let( + blocks = mz_blocks( + [1, 1], + rows, columns + ), + dot_pts = dedup( + concat( + [ + for(block = blocks) + let( + x = mz_get(block, "x"), + y = mz_get(block, "y"), + wall_type = mz_get(block, "w"), + pts = wall_type == "UPPER_WALL" ? _mz_hamiltonian_upper(x, y) : + wall_type == "RIGHT_WALL" ? _mz_hamiltonian_right(x, y) : + wall_type == "UPPER_RIGHT_WALL" ? _mz_hamiltonian_upper_right(x, y) : [] + ) + each pts + ], + [for(x = [0:columns * 2 - 1]) [x, 0]], + [for(y = [0:rows * 2 - 1]) [0, y]] + ) + ) + ) + _mz_hamiltonian_travel(dot_pts, start, rows * columns * 4); \ No newline at end of file