in src/h3lib/lib/polygon.c [180:232]
bool cellBoundaryCrossesGeoLoop(const GeoLoop *geoloop, const BBox *loopBBox,
const CellBoundary *boundary,
const BBox *boundaryBBox) {
if (!bboxOverlapsBBox(loopBBox, boundaryBBox)) {
return false;
}
LongitudeNormalization loopNormalization;
LongitudeNormalization boundaryNormalization;
bboxNormalization(loopBBox, boundaryBBox, &loopNormalization,
&boundaryNormalization);
CellBoundary normalBoundary = *boundary;
for (int i = 0; i < boundary->numVerts; i++) {
normalBoundary.verts[i].lng =
normalizeLng(normalBoundary.verts[i].lng, boundaryNormalization);
}
BBox normalBoundaryBBox = {
.north = boundaryBBox->north,
.south = boundaryBBox->south,
.east = normalizeLng(boundaryBBox->east, boundaryNormalization),
.west = normalizeLng(boundaryBBox->west, boundaryNormalization)};
LatLng loop1;
LatLng loop2;
for (int i = 0; i < geoloop->numVerts; i++) {
loop1 = geoloop->verts[i];
loop1.lng = normalizeLng(loop1.lng, loopNormalization);
loop2 = geoloop->verts[(i + 1) % geoloop->numVerts];
loop2.lng = normalizeLng(loop2.lng, loopNormalization);
// Quick check if the line segment overlaps our bbox
if ((loop1.lat >= normalBoundaryBBox.north &&
loop2.lat >= normalBoundaryBBox.north) ||
(loop1.lat <= normalBoundaryBBox.south &&
loop2.lat <= normalBoundaryBBox.south) ||
(loop1.lng <= normalBoundaryBBox.west &&
loop2.lng <= normalBoundaryBBox.west) ||
(loop1.lng >= normalBoundaryBBox.east &&
loop2.lng >= normalBoundaryBBox.east)) {
continue;
}
for (int j = 0; j < normalBoundary.numVerts; j++) {
if (lineCrossesLine(
&loop1, &loop2, &normalBoundary.verts[j],
&normalBoundary.verts[(j + 1) % normalBoundary.numVerts])) {
return true;
}
}
}
return false;
}