in src/h3lib/lib/algos.c [452:532]
int H3_EXPORT(hexRangeDistances)(H3Index origin, int k, H3Index* out,
int* distances) {
// Return codes:
// 1 Pentagon was encountered
// 2 Pentagon distortion (deleted k subsequence) was encountered
// Pentagon being encountered is not itself a problem; really the deleted
// k-subsequence is the problem, but for compatibility reasons we fail on
// the pentagon.
// k must be >= 0, so origin is always needed
int idx = 0;
out[idx] = origin;
if (distances) {
distances[idx] = 0;
}
idx++;
if (H3_EXPORT(h3IsPentagon)(origin)) {
// Pentagon was encountered; bail out as user doesn't want this.
return HEX_RANGE_PENTAGON;
}
// 0 < ring <= k, current ring
int ring = 1;
// 0 <= direction < 6, current side of the ring
int direction = 0;
// 0 <= i < ring, current position on the side of the ring
int i = 0;
// Number of 60 degree ccw rotations to perform on the direction (based on
// which faces have been crossed.)
int rotations = 0;
while (ring <= k) {
if (direction == 0 && i == 0) {
// Not putting in the output set as it will be done later, at
// the end of this ring.
origin =
h3NeighborRotations(origin, NEXT_RING_DIRECTION, &rotations);
if (origin == 0) { // LCOV_EXCL_BR_LINE
// Should not be possible because `origin` would have to be a
// pentagon
return HEX_RANGE_K_SUBSEQUENCE; // LCOV_EXCL_LINE
}
if (H3_EXPORT(h3IsPentagon)(origin)) {
// Pentagon was encountered; bail out as user doesn't want this.
return HEX_RANGE_PENTAGON;
}
}
origin = h3NeighborRotations(origin, DIRECTIONS[direction], &rotations);
if (origin == 0) { // LCOV_EXCL_BR_LINE
// Should not be possible because `origin` would have to be a
// pentagon
return HEX_RANGE_K_SUBSEQUENCE; // LCOV_EXCL_LINE
}
out[idx] = origin;
if (distances) {
distances[idx] = ring;
}
idx++;
i++;
// Check if end of this side of the k-ring
if (i == ring) {
i = 0;
direction++;
// Check if end of this ring.
if (direction == 6) {
direction = 0;
ring++;
}
}
if (H3_EXPORT(h3IsPentagon)(origin)) {
// Pentagon was encountered; bail out as user doesn't want this.
return HEX_RANGE_PENTAGON;
}
}
return HEX_RANGE_SUCCESS;
}