Представление двумерного круга в виде одномерного массива (геометрия такси, окрестности фон Неймана) - PullRequest
0 голосов
/ 14 сентября 2018

Имея радиус и площадь круга в геометрии такси (окрестности фон Неймана), я хотел бы сопоставить все «поля» (буквы «o» на изображении) с индексами массива 1D и обратно.

Я хотел бы преобразовать индекс 1-го массива на основе 0 в координаты x, y и обратно (0, 0 предполагается в качестве центра).

   o  radius=0, area=1

   o
  ooo  radius=1, area=5
   o

   o
  ooo
 ooooo  radius=2, area=13
  ooo
   o

   o
  ooo
 ooooo
ooooooo  radius=3, area=25
 ooooo
  ooo
   o


x, y = taxicab.circlePositionFromIndex(index, radius)

index = taxicab.circleIndexFromPosition(x, y, radius)

То, что я до сих пор достиг, этофункция, которая вычисляет координаты x, y путем итерации по кругу:

var _DIRECTIONS = [1, -1, -1, -1, -1, 1, 1, 1];

function indexToPosition(index, radius) {
    var i = 0;

    for (var r = 0; r <= radius; r++) {
        var x = 0, y = r;
        var direction = 0;
        var segment = 0;

        do {
            if (i === index)
                return [x, y];

            segment += 1;
            x += _DIRECTIONS[direction];
            y += _DIRECTIONS[direction+1];
            i += 1;

            if (segment === radius) {
                direction += 2;
                segment = 0;
            }
        } while (x !== 0 || y !== r);
    }

    return -1;
};

Эта функция кажется слишком сложной для задачи, должен быть более простой способ.Также это работает только в одну сторону.

Для вычисления площади круга я использую эту функцию:

function area(radius) {
    return 1 + 2 * radius * (radius + 1);
}

1 Ответ

0 голосов
/ 14 сентября 2018

Если нумерация такая: (иначе она может быть отображена в желаемые координаты)

      0
   1  2  3
4  5  6  7  8   
   9 10 11
     12

               (0,0)
        (1,0)  (1,1)   (1,2)
 (2,0)  (2,1)  (2,2)   (2,3)  (2,4)
        (3,0)  (3,1)   (3,2)
               (4,0)

, тогда для верхнего треугольника номер строки равен

 row = Floor(Sqrt(index))

, а столбец -

 col = index - row * row

Если рассчитанная строка больше радиуса, сделайте зеркальное отображение:

id = area - 1 - index
row_m  = Floor(Sqrt(id))
col_m = id - row_m * row_m

row = radius * 2 - row_m
col = row_m * 2 - col_m

quick check:
index = 6
row = 2
col = 6-4=2

index = 10
id = 2
row_m = 1
col_m = 1
row = 2*2-1 = 3
col = 2*1-1 = 1
...