Reputation: 3174
Having a radius and an area of a circle in taxicab geometry (Von Neumann neighborhood), I would like to map all "fields" ("o" letters on the image) to 1D array indices and back.
I would like to convert from 1D array 0-based index to x, y coordinates and back (0, 0 is assumed to be the center).
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)
What I have accomplished so far is this function which calculates x, y coordinates by iterating over a circle:
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;
};
This function seems to be over-complicated for the task, there must be a simpler way. Also it works only one way.
To calculate area of a circle I'm using this function:
function area(radius) {
return 1 + 2 * radius * (radius + 1);
}
Upvotes: 0
Views: 221
Reputation: 80177
If numbering is like this: (else it could be mapped into desired coordinates)
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)
then for upper triangle number of row is
row = Floor(Sqrt(index))
and column is
col = index - row * row
If calculated row is larger then radius, make mirroring:
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
Upvotes: 1