in h3_localij.c [677:727]
H3Error H3_EXPORT(gridPathCells)(H3Index start, H3Index end, H3Index *out) {
int64_t distance;
H3Error distanceError = H3_EXPORT(gridDistance)(start, end, &distance);
// Early exit if we can't calculate the line
if (distanceError) {
return distanceError;
}
// Get IJK coords for the start and end. We've already confirmed
// that these can be calculated with the distance check above.
CoordIJK startIjk = {0};
CoordIJK endIjk = {0};
// Convert H3 addresses to IJK coords
H3Error startError = cellToLocalIjk(start, start, &startIjk);
if (NEVER(startError)) {
// Unreachable because this was called as part of gridDistance
return startError;
}
H3Error endError = cellToLocalIjk(start, end, &endIjk);
if (NEVER(endError)) {
// Unreachable because this was called as part of gridDistance
return endError;
}
// Convert IJK to cube coordinates suitable for linear interpolation
ijkToCube(&startIjk);
ijkToCube(&endIjk);
double invDistance = distance ? 1.0 / (double)distance : 0;
double iStep = (double)(endIjk.i - startIjk.i) * invDistance;
double jStep = (double)(endIjk.j - startIjk.j) * invDistance;
double kStep = (double)(endIjk.k - startIjk.k) * invDistance;
CoordIJK currentIjk = {startIjk.i, startIjk.j, startIjk.k};
for (int64_t n = 0; n <= distance; n++) {
cubeRound((double)startIjk.i + iStep * n,
(double)startIjk.j + jStep * n,
(double)startIjk.k + kStep * n, ¤tIjk);
// Convert cube -> ijk -> h3 index
cubeToIjk(¤tIjk);
H3Error currentError = localIjkToCell(start, ¤tIjk, &out[n]);
if (currentError) {
// The cells between `start` and `end` may fall in pentagon
// distortion.
return currentError;
}
}
return E_SUCCESS;
}