H3Error H3_EXPORT()

in src/h3lib/lib/algos.c [565:648]


H3Error H3_EXPORT(gridDiskDistancesUnsafe)(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.
    if (k < 0) {
        return E_DOMAIN;
    }

    // k must be >= 0, so origin is always needed
    int idx = 0;
    out[idx] = origin;
    if (distances) {
        distances[idx] = 0;
    }
    idx++;

    if (H3_EXPORT(isPentagon)(origin)) {
        // Pentagon was encountered; bail out as user doesn't want this.
        return E_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.
            H3Error neighborResult = h3NeighborRotations(
                origin, NEXT_RING_DIRECTION, &rotations, &origin);
            if (neighborResult) {
                // Should not be possible because `origin` would have to be a
                // pentagon
                // TODO: Reachable via fuzzer
                return neighborResult;
            }

            if (H3_EXPORT(isPentagon)(origin)) {
                // Pentagon was encountered; bail out as user doesn't want this.
                return E_PENTAGON;
            }
        }

        H3Error neighborResult = h3NeighborRotations(
            origin, DIRECTIONS[direction], &rotations, &origin);
        if (neighborResult) {
            return neighborResult;
        }
        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(isPentagon)(origin)) {
            // Pentagon was encountered; bail out as user doesn't want this.
            return E_PENTAGON;
        }
    }
    return E_SUCCESS;
}