1

I have a grid of tiles each with coordinates such as (-3, 5) or (1, 540) I want to generate a unique seed for each tile but I haven't found a way to do such

7n7o
  • 35
  • 4
  • 1
    This looks like an [XY problem](https://en.wikipedia.org/wiki/XY_problem). You can index Lua tables with strings like `"(-3,5)"`. – lhf Dec 28 '21 at 09:54

2 Answers2

3

You need some kind of "pairing function" - Wiki describes such functions for natural numbers while you need integers including negative ones.

You can enumerate all integer points at coordinate plane in spiral manner

       ^   OY
       |
 16 15 14 13 12
 17  4  3  2 11
 18  5  0  1 10 ==> OX
 19  6  7  8  9
 20 21 22 23 24

So, for example, point -2,-2 has index 20

To calculate such index from coordinates, you can use simple algorithm (details here)

if y * y >= x * x then begin
  p := 4 * y * y - y - x;
  if y < x then
    p := p - 2 * (y - x)
end
else begin
  p := 4 * x * x - y - x;
  if y < x then
    p := p + 2 *(y - x)
end;

You don't ask for reverse mapping, but it is definitely possible (layer number is (1 + floor(sqrt(p))) / 2 and so on)

To complete: Python function for reverse mapping

def ptoxy(p):
    layer = (int(math.sqrt(p)) + 1) // 2   # integer division
    topleft = 4*layer*layer
    if p <= topleft:
        if p <= topleft - 2 * layer:
            return [layer, 3*layer +  p - topleft]
        else:
            return [-layer + topleft - p, layer]
    else:
        if p >= topleft + 2 * layer:
            return [p-topleft - 3*layer, -layer]
        else:
            return [-layer, layer-p + topleft]

and link to quick-made test

MBo
  • 77,366
  • 5
  • 53
  • 86
  • I believe this would change the index for each point as the grid updates, I need something that would simply take 2 numbers and return some sort of unique value for those 2 numbers. – 7n7o Dec 28 '21 at 10:45
  • Nevermind this may be what I'm looking for – 7n7o Dec 28 '21 at 10:47
  • For limited grid size you can use another methods - for example, if all coordinates are 16-bits signed integers - just combine them in single 32-bit value (`(x<<16) or y`) – MBo Dec 28 '21 at 11:16
1

If you have a grid of tiles, you may consider that you have a first tile, at the top-left corner and a last tile at the bottom-right corner.

[0] [1] [2]
[3] [4] [5]
[6] [7] [8]

But the [Row:Col] notation is more handy.

[0:0] [0:1] [0:2]
[1:0] [1:1] [1:2]
[2:0] [2:1] [2:2]

So you can access the [Row:Col] element with the formula:

ColumnCount = 3
Element = (Row * ColumnCount) + Col

For example (2:1) offset in your grid will be 2*3+1 which is 7.

[0:0] [0:1] [0:2]
[1:0] [1:1] [1:2]
[2:0] [2:1] [2:2]
      --v--
     2*3+1 = 7

It's simple and each tile will have a unique identifier.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Robert
  • 2,711
  • 7
  • 15
  • The grid is infinite and can go negative – 7n7o Dec 28 '21 at 05:26
  • I'm more asking for a way to generate a unique number for any 2 given numbers, positive or negative – 7n7o Dec 28 '21 at 05:27
  • Quick answer: `f = lambda x,y: 2**x * (2 * y + 1)` gives a unique mapping from pairs of nonnegative integers to positive integers, because every positive number `n` has a unique decomposition as a power of 2 (`2**x`) multiplied by an odd number (`2 * y + 1`). – Stef Dec 28 '21 at 09:16
  • 1
    @Stef But author needs negative values as well – MBo Dec 28 '21 at 09:24
  • Your answer is pretty interesting, I upvoted! – Robert Dec 28 '21 at 09:29