in src/h3lib/lib/h3Index.c [1333:1393]
H3Error H3_EXPORT(childPosToCell)(int64_t childPos, H3Index parent,
int childRes, H3Index *child) {
// Validate resolution
if (childRes < 0 || childRes > MAX_H3_RES) {
return E_RES_DOMAIN;
}
// Validate parent resolution
int parentRes = H3_GET_RESOLUTION(parent);
if (childRes < parentRes) {
return E_RES_MISMATCH;
}
// Validate child pos
H3Error childPosErr = validateChildPos(childPos, parent, childRes);
if (childPosErr) {
return childPosErr;
}
int resOffset = childRes - parentRes;
*child = parent;
int64_t idx = childPos;
H3_SET_RESOLUTION(*child, childRes);
if (H3_EXPORT(isPentagon)(parent)) {
// Pentagon tile logic. Pentagon tiles skip the 1 digit, so the offsets
// are different
bool inPent = true;
for (int res = 1; res <= resOffset; res++) {
int64_t resWidth = _ipow(7, resOffset - res);
if (inPent) {
// While we are inside a parent pentagon, we need to check if
// this cell is a pentagon, and if not, we need to offset its
// digit to account for the skipped direction
int64_t pentWidth = 1 + (5 * (resWidth - 1)) / 6;
if (idx < pentWidth) {
H3_SET_INDEX_DIGIT(*child, parentRes + res, 0);
} else {
idx -= pentWidth;
inPent = false;
H3_SET_INDEX_DIGIT(*child, parentRes + res,
(idx / resWidth) + 2);
idx %= resWidth;
}
} else {
// We're no longer inside a pentagon, continue as for hex
H3_SET_INDEX_DIGIT(*child, parentRes + res, idx / resWidth);
idx %= resWidth;
}
}
} else {
// Hexagon tile logic. Offsets are simple powers of 7
for (int res = 1; res <= resOffset; res++) {
int64_t resWidth = _ipow(7, resOffset - res);
H3_SET_INDEX_DIGIT(*child, parentRes + res, idx / resWidth);
idx %= resWidth;
}
}
return E_SUCCESS;
}