0

It is well-known, that if one wants to layout square grid(aka matrix) of real numbers he can use array with row-major order. Let's draw neighbourhood of some element i:

...................................
...|i-width-1|i-width|i-width+1|...
...|   i-1   |   i   |   i+1   |...
...|i+width-1|i+width|i+width+1|...
...................................

Let us for simplicity assume that i somewhere in the middle of square grid, so no bordering issues.(We can add %(width*height) and get connected on borders grid). So if one wants to do something with each element in neighbourhood of i'th element one should do:

//function which does something with element at idx
void DoSomethinWithElement(size_t idx);

//left neighbour
DoSomethinWithElement(i-1);
//right neighbour
DoSomethinWithElement(i+1);
//top neighbour
DoSomethinWithElement(i-width);
//bottom neighbour
DoSomethinWithElement(i+width);

I want to generalize this algorithm for any type of regular polygon grid (i.e. triangle, square, pentagonal, hexagonal etc.) Regular means that it constructed only from one type of polygon (i.e only from triangles).

How to generalize for any type of polygon grid: 1. Layout of other grid in array? 2. These N(for square mesh four) statements in a loop?

The problem "How to find all neighbors of a tile in a polygonal grid?" is solved quickly using graphs. But I want to use arrays so I could copy them to graphics card with CUDA.

Examples of grids:

  1. Triangular
  2. Pentagonal
  3. Hexagonal
decltype_auto
  • 1,706
  • 10
  • 19
DoctorMoisha
  • 1,613
  • 14
  • 25
  • What does a pentagonal grid look like? – eerorika Nov 05 '15 at 14:19
  • Forget about generalizing access to neighbors for a moment. How do you generalize storing a non-rectangular grid itself - say, one composed of pentagons? Did I misunderstand the question, and the grid is actually made of squares, and the shape refers only to the boundaries? – Sergey Kalinichenko Nov 05 '15 at 14:19
  • You cannot create fully regular pentagonal grid. Also it depends on a lot of parameters. For instance what form do the non-rectangular grids have? A triangular grid is divided into triangles or they build up a nearly rectangular shape? You should give more information about other shapes. – Lasoloz Nov 05 '15 at 14:24
  • @dasblinkenlight Good point, I've edited the question. Grid can be constructed with polygons with any numebr of sides, am I wrong? For example here is http://gwydir.demon.co.uk/jo/tess/bigpent.gif pentagonal grid – DoctorMoisha Nov 05 '15 at 14:28
  • @DoctorMoisha You are right about constructing a grid of polygons. However, there is no obvious way to express coordinates on such grid, because the traditional `{row, column}` pair is hard to translate. – Sergey Kalinichenko Nov 05 '15 at 14:35
  • "These four statements in a loop?" shouldn't this be "N statements in a loop", because a cell in a grid constructed of N-sided polygons has N neighbors. – Sergey Kalinichenko Nov 05 '15 at 14:37
  • @dasblinkenlight Edited – DoctorMoisha Nov 05 '15 at 14:41
  • You could look into half-edge data structure which is an efficient way of storing arbitrary planar graphs. You could take [this](https://en.wikipedia.org/wiki/Doubly_connected_edge_list) as a starting point. – Rostislav Nov 05 '15 at 14:45
  • better tag it with cuda if it's for CUDA. – decltype_auto Nov 05 '15 at 16:08
  • @decltype_auto: Why? What is there in this question that is specific to CUDA programming. If the last sentence of the question was deleted, would it change any of the answers? – talonmies Nov 05 '15 at 18:26
  • @talonmies The justification for his bottom-up approach. – decltype_auto Nov 05 '15 at 18:58

2 Answers2

4

I want to generalize this algorithm for any type of regular polygon grid (i.e. triangle, square, pentagonal, hexagonal etc.)

Your definition of regular polygon grid is unusual. Typically you may not rotate or mirror the faces of the grid (tiling) for it to be considered regular. There are only 3 regular tilings (triangle, square, hexagon). All pentagonal tilings require mirroring or rotation or both.

Let's simplify your problem to this: "How to find all neighbors of a face in a polygonal grid?" Once you've got that figured out, it's trivial to call a function on each neighbor.

Grids are graphs with certain limitations. It is possible to generalize the search for neighbors by representing the grid with a general graph. The vertices of the graph represent the faces and they have edges to their neighbors. Graph of a grid is a planar graph. When the grid is represented by a graph, the problem becomes: "Given a vertex in a graph, how do I find all adjacent vertices?"

Note that the vertices and edges of the graph are not the same thing as the vertices and edges of the grid. For example, the grid-vertices of a hexagonal grid have three connected edges, while the faces have six neighboring faces and therefore the graph-vertices have six edges each.

One way to represent graphs is the adjacency list. In this representation, you simply need to look up the adjacency list of the vertex to find all it's neighbors.

But I want to use arrays

Well since the size of each adjacency list is constant, they can be implemented with arrays like in decltype_auto's answer. Or you can represent the graph with an adjacency matrix.

But if you want a generic algorithm for any tabular representation of a grid, then I think that you've painted yourself into a corner with that requirement. Each representation is different and you'll need a different algorithm for each.

eerorika
  • 232,697
  • 12
  • 197
  • 326
1

You can represent the adjacencies of K-polygonal grid of polygon count N by a 1D vector v of N*K length, or a 2D NxK matrix M. Use std::size_t -1, a nullptr or whatever suites the reference type you've stored in v or M to indicate missing neighbors at the border.

Given such a NxK matrix M:

For the neighbors of polygon n you iterate from M[n][0] to M[n][K-1], fetch the neighbors by whatever reference you've stored in M, and apply whatever function you want on them.

decltype_auto
  • 1,706
  • 10
  • 19
  • @user2079303 After seeing his 'CUDA' addendum my crystal ball told me that this may already fulfill his requirements. – decltype_auto Nov 05 '15 at 16:17
  • Whoops, I didn't quite get your answer at first, my comment was bogus. This is actually an adjacency list, except since the size of each list is constant, it can be implemented with an array. – eerorika Nov 05 '15 at 16:23
  • @user2079303 Yup. with some `traits<..>` one could even plug that under boost::graph. – decltype_auto Nov 05 '15 at 16:30