local sides = {
north = 2,
south = 3,
west = 4,
east = 5,
}
local testN = 22
-- центр, реальные координаты
local startX, startZ = 0, 0
-- кол-во кругов
local radius = 2
-- расстояние между "кругами"
local distance = 1
-- направление взгляда на поле
-- нумерация идёт слева направо и сверху вниз
local orientation = sides.north
local step = distance + 1
local offset = radius*step
local size = offset*2+1
-- преобразование виртуальной системы координат в реальную
-- Minecraft
--
-- z
-- (-)
-- north
-- x (-) west east (+) x
-- south
-- (+)
-- z
-- условная система координат
--
--
-- (-x)
-- (-z) ^ (+z)
-- (+x)
-- ^ направление взгляда на поле
-- нумерация идёт слева направо и сверху вниз
local toRealFn = {
[sides.east] = function(virtX, virtZ) return startX - virtX, startZ + virtZ end,
[sides.south] = function(virtX, virtZ) return startX - virtZ, startZ - virtX end,
[sides.west] = function(virtX, virtZ) return startX + virtX, startZ - virtZ end,
[sides.north] = function(virtX, virtZ) return startX + virtZ, startZ + virtX end,
}
local d = radius*2+1
local maxN = d^2
local function getCoord(n)
local xx, zz = math.floor((n-1)/d)*step-offset, math.fmod(n-1, d)*step-offset
return toRealFn[orientation](xx, zz)
end
local n = 0
for xx = -offset, offset, step do
for zz = -offset, offset, step do
n = n + 1
local x, z = toRealFn[orientation](xx, zz)
print(n, x, z)
end
end
print("["..testN.."]".."=", getCoord(testN))
Вот вывод:
radius=2, distance=1
1 -4 -4
2 -2 -4
3 0 -4
4 2 -4
5 4 -4
6 -4 -2
7 -2 -2
8 0 -2
9 2 -2
10 4 -2
11 -4 0
12 -2 0
13 0 0
14 2 0
15 4 0
16 -4 2
17 -2 2
18 0 2
19 2 2
20 4 2
21 -4 4
22 -2 4
23 0 4
24 2 4
25 4 4
[22]= -2 4
radius=1, distance=1
1 -2 -2
2 0 -2
3 2 -2
4 -2 0
5 0 0
6 2 0
7 -2 2
8 0 2
9 2 2
[8]= 0 2
Если не нужна нумерация слева направо и сверху вниз по направлению взгляда, то можно упростить код преобразования координат, захардкодив конкретное направление.
Код преобразования координат нужно потестирвать.