void _faceIjkPentToGeoBoundary()

in src/h3lib/lib/faceijk.c [506:599]


void _faceIjkPentToGeoBoundary(const FaceIJK* h, int res, GeoBoundary* g) {
    int adjRes = res;
    FaceIJK centerIJK = *h;
    FaceIJK fijkVerts[NUM_PENT_VERTS];
    _faceIjkPentToVerts(&centerIJK, &adjRes, fijkVerts);

    // convert each vertex to lat/lon
    // adjust the face of each vertex as appropriate and introduce
    // edge-crossing vertices as needed
    g->numVerts = 0;
    FaceIJK lastFijk;
    for (int vert = 0; vert < NUM_PENT_VERTS + 1; vert++) {
        int v = vert % NUM_PENT_VERTS;

        FaceIJK fijk = fijkVerts[v];

        _adjustPentVertOverage(&fijk, adjRes);

        // all Class III pentagon edges cross icosa edges
        // note that Class II pentagons have vertices on the edge,
        // not edge intersections
        if (isResClassIII(res) && vert > 0) {
            // find hex2d of the two vertexes on the last face

            FaceIJK tmpFijk = fijk;

            Vec2d orig2d0;
            _ijkToHex2d(&lastFijk.coord, &orig2d0);

            int currentToLastDir = adjacentFaceDir[tmpFijk.face][lastFijk.face];

            const FaceOrientIJK* fijkOrient =
                &faceNeighbors[tmpFijk.face][currentToLastDir];

            tmpFijk.face = fijkOrient->face;
            CoordIJK* ijk = &tmpFijk.coord;

            // rotate and translate for adjacent face
            for (int i = 0; i < fijkOrient->ccwRot60; i++) _ijkRotate60ccw(ijk);

            CoordIJK transVec = fijkOrient->translate;
            _ijkScale(&transVec, unitScaleByCIIres[adjRes] * 3);
            _ijkAdd(ijk, &transVec, ijk);
            _ijkNormalize(ijk);

            Vec2d orig2d1;
            _ijkToHex2d(ijk, &orig2d1);

            // find the appropriate icosa face edge vertexes
            int maxDim = maxDimByCIIres[adjRes];
            Vec2d v0 = {3.0 * maxDim, 0.0};
            Vec2d v1 = {-1.5 * maxDim, 3.0 * M_SQRT3_2 * maxDim};
            Vec2d v2 = {-1.5 * maxDim, -3.0 * M_SQRT3_2 * maxDim};

            Vec2d* edge0;
            Vec2d* edge1;
            switch (adjacentFaceDir[tmpFijk.face][fijk.face]) {
                case IJ:
                    edge0 = &v0;
                    edge1 = &v1;
                    break;
                case JK:
                    edge0 = &v1;
                    edge1 = &v2;
                    break;
                case KI:
                default:
                    assert(adjacentFaceDir[tmpFijk.face][fijk.face] == KI);
                    edge0 = &v2;
                    edge1 = &v0;
                    break;
            }

            // find the intersection and add the lat/lon point to the result
            Vec2d inter;
            _v2dIntersect(&orig2d0, &orig2d1, edge0, edge1, &inter);
            _hex2dToGeo(&inter, tmpFijk.face, adjRes, 1,
                        &g->verts[g->numVerts]);
            g->numVerts++;
        }

        // convert vertex to lat/lon and add to the result
        // vert == NUM_PENT_VERTS is only used to test for possible intersection
        // on last edge
        if (vert < NUM_PENT_VERTS) {
            Vec2d vec;
            _ijkToHex2d(&fijk.coord, &vec);
            _hex2dToGeo(&vec, fijk.face, adjRes, 1, &g->verts[g->numVerts]);
            g->numVerts++;
        }

        lastFijk = fijk;
    }
}