Function S2Polygon.initializeToIntersection

Initialize this polygon to the intersection, union, difference (A - B), or symmetric difference (XOR) of the given two polygons.

void initializeToIntersection (
  S2Polygon a,
  S2Polygon b
);

"snap_function" allows you to specify a minimum spacing between output vertices, and/or that the vertices should be snapped to a discrete set of points (e.g. S2CellId centers or E7 lat/lng coordinates). Any snap function can be used, including the IdentitySnapFunction with a snap_radius of zero (which preserves the input vertices exactly).

The boundary of the output polygon before snapping is guaranteed to be accurate to within S2::kIntersectionError of the exact result. Snapping can move the boundary by an additional distance that depends on the snap function. Finally, any degenerate portions of the output polygon are automatically removed (i.e., regions that do not contain any points) since S2Polygon does not allow such regions.

See S2Builder and s2builderutil for more details on snap functions. For example, you can snap to E7 coordinates by setting "snap_function" to

s2builderutil

:IntLatLngSnapFunction(7).

The default snap function is the IdentitySnapFunction with a snap radius of S2::kIntersectionMergeRadius (equal to about 1.8e-15 radians or 11 nanometers on the Earth's surface). This means that vertices may be positioned arbitrarily, but vertices that are extremely close together can be merged together. The reason for a non-zero default snap radius is that it helps to eliminate narrow cracks and slivers when T-vertices are present. For example, adjacent S2Cells at different levels do not share exactly the same boundary, so there can be a narrow crack between them. If a polygon is intersected with those cells and the pieces are unioned together, the result would have a narrow crack unless the snap radius is set to a non-zero value.

Note that if you want to encode the vertices in a lower-precision representation (such as S2CellIds or E7), it is much better to use a suitable SnapFunction rather than rounding the vertices yourself, because this will create self-intersections unless you ensure that the vertices and edges are sufficiently well-separated first. In particular you need to use a snap function whose min_edge_vertex_separation() is at least twice the maximum distance that a vertex can move when rounded.