filter icosahedral projection on only one face

Hi all!

I’m trying to create a polyhedral map projection in observable that shows just one face at time.

Here is what i get using d3.geoClipPolygon function:

It works for some faces bout fails for others, and i don’t understand if it’s a problem of my code and my understanding of the library or something else

thanks!

the issue is that clipping a polygon with itself is ill-defined. Clipping means checking, for each point, if it is on either side of the polygon (interior or exterior), but in this case all the points are on the edge.

If you use a slightly modified polygon in clipPolygon, then the transform is going to be well defined.

For instance you can contract it by a tiny percentage (1e-12) towards its centroid with:

function shrink(p) {
  const c = d3.geoCentroid(p);
  return {
    ...p,
    coordinates: p.coordinates.map((r) => 
      r.map((u) => d3.geoInterpolate(u, c)(1e-12))
    )
  };
}

and calling

clipped = d3
  .geoIcosahedral()
  .rotate([-83.65929, 25.44458, -87.45184])
  .preclip(
    d3.geoClipPolygon(shrink(projection.polygons().features[selectedId].geometry))
  )
1 Like

Thank you @Fil! Always on point!