2021-06-03 00:20:40

Suppose I have the following matrix:

[[1, 1, 1, 0, 0, 0]
[1, 1, 1, 0, 0, 0]
[1, 1, 1, 0, 0, 0]]

No tiles can hold other values besides 0 or 1. In this situation, 0 represents walkable space, while 1 represents a wall. How can I output the minimum amount of walls and open spaces as boxes? The previous matrix would produce 2 objects: A box with a value of wall from 0 to 2 on x and y, and a box with a value of platform from 2 to 4 on x and y axis. Suppose we have something like this, though:

[[0, 0, 1, 1, 0, 0]
[0, 1, 1, 1, 0, 0]
[0, 1, 1, 1, 0, 0]]

In this case, box with a value of platform is generated at 0 on the x axis from 0 to 2 on the y axis. Another box with a value of platform is generated at 1, 0, it being only 1 tile wide. A final box related to the platforms is generated from 4 to 5 and 0 to 2 on the x and y-axis. The walls are a little more ambiguous because there are two possible configurations in which we could have the least amount of walls. We could spawn a polygon from 1 to 3 on the x and 1 to 2 on the y and another polygon from 2 to 3 on the x axis and 0 on the y axis. We can also invert these. Another valid choice would be to have a wall from 2 to 3 on the x and 0 to 2 on the y and another wall at 1 on the x-axis going from 1 to 2 on the y-axis. These are both equal because when calculating their area the resulting two integers equal. As such, either output is acceptable.
Trouble is, I don't know what exactly to look up to even begin drawing up a rough draft of how this is going to look. I've stumbled on Tesslazation (I think that's how you spell it) but that is focused on rendering and more often produces small triangles rather than large rectangles / squares. Is this another design issue -- no perfect formula, or am I just typing wrong words into Google?

2021-06-03 01:33:51

Hm, if your referring to creating hollow boxes in array like structures, that can best be achieved through array slicing, such as with numpy. Example:

import numpy

box = numpy.zeros((10,10),dtype='uint8')

box[1:5:,1:5:] = 1
box[2:4:,2:4:] = 0

print(box)

That produces this output:

[[0 0 0 0 0 0 0 0 0 0]
 [0 1 1 1 1 0 0 0 0 0]
 [0 1 0 0 1 0 0 0 0 0]
 [0 1 0 0 1 0 0 0 0 0]
 [0 1 1 1 1 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]]
-BrushTone v1.3.3: Accessible Paint Tool
-AudiMesh3D v1.0.0: Accessible 3D Model Viewer

2021-06-03 01:50:57

No. The goal is to derive the optimal set of boxes which cover a 2d matrix. Each box can be filled with either 0 or 1, not both, and the algorithm should produce the minimal amount of boxes which could represent the 2d matrix. I.e, my first example in my post (Please note that the upper bound is inclusive in this case):

input matrix: [
[1, 1, 1, 0, 0, 0]
[1, 1, 1, 0, 0, 0]
[1, 1, 1, 0, 0, 0]]
Output boxes:
box(0, 2, 0, 2, filled_width=0)
box(3, 5, 3, 5, filled_with=1)

A second example:

input matrix: [
[0, 0, 1, 1, 0, 0]
[0, 0, 1, 1, 0, 0]
[0, 0, 1, 1, 0, 0]
Output boxes:
box(0, 1, 0, 2, filled_with=0)
box(2, 3, 0, 2, filled_with=1)
box(4, 5, 0, 2, filled_with=0)

2021-06-03 05:05:52

I don't know of a general solution to this problem, and your also talking like you want to extract features, e.g. walls versus floor.  The easy way is to just start at the top left and try expanding boxes right and/or down until you can't, then keep running the algorithm repeatedly on un-boxed tiles.  I haven't coded this myself but there's a few ways you can do it depending on how much time your algorithm has to run.  If the requirement of it being "the minimum number of boxes" isn't a hard requirement this will almost certainly give you something good enough, but it's hard to tell if this is a brain teaser/puzzle, or something you need for a project.

If it's for a game, though, consider a cross:

0, 1, 0
1, 1, 1
0, 1, 0

This obviously has a wall in the middle and 2 floor tiles, one on either side.  Do you want 2 floor tiles and a wall, or 1 floor and 2 wall tiles?  It seems to me that you'd want 1 wall and 2 separate chunks of floor for a game, as to not make the player figure out what subdivides it, but technically speaking either solution works.  If it's not just the minimum number of boxes but a specific minimal solution that gives friendly data for a radar or something in something like BK3, then you're going to get close but should be prepared to hand-edit the data afterword.  Especially for "fun" cases like: if you're climbing a tower, maybe you want the walls to be divided by the floors to highlight the vertical direction and what can be climbed to, rather than the floors divided by the walls to highlight the horizontal direction and what can be jumped.

If this is indeed game mapping--well. Ammo will be using semantic information coded in Lua as the maps in order to avoid this entire problem, at least if the prototypes that I haven't yet written work out.  If the prototypes don't work out then back to the drawing board.  But overall these days tilemaps make me sad inside, in the sense that if you do one you probably still need to mark it up afterword, or you're leaving a lot of things on the table.

My Blog
Twitter: @ajhicks1992

2021-06-03 07:57:36

It is sort of for a game.  The reason why I was asking was because maze algorithms, which are the source of my 2D matrix, only work on those or a set of cells. They don’t work on boxes.  You can make a box by using scaling, but I would rather avoid that.  The issue of minimal amount of objects comes in because the game in question is written in BGT and I do not know what internal data structures they’re using. Their map parser simply takes the vertices of the rectangle and or a square and spawns tiles based on those  values.  Regarding wall ambiguity, or uncertainty in general, I don’t really care as long as we don’t lose area based on the choices.

2021-06-03 18:14:54

Yeah, so you don't need the absolute minimum.  You just need good enough.  What I described in 4 will be good enough for that--it's easily a 10x to 100x decrease.

But. And this is a pretty big but.  You're going to have to really carefully tune those maze algorithms.  If they don't produce outputs that can be turned into boxes in a friendly fashion, no algorithm like this will help you.  You can only get to an efficient set of boxes with lots of long corridors and big open spaces without jagged edges.

My Blog
Twitter: @ajhicks1992