The collar of a closed polygon is two-sided #
Schoenflies/Strip.lean builds the blocks of Lemma 1.8 and proves the hard local half of the
statement: the two labelled sides are disjoint. This module closes the lemma for a closed
polygon by supplying the two remaining global facts.
Each side is connected. The blueprint says "consecutive edge and vertex blocks overlap in a nonempty labelled half-strip, so the union of all left pieces is connected". Here that overlap is produced explicitly:
StripData.mem_overlapL_startputs the point at frame position(3 lam / 2, rho / 2)in bothblockL iandsectorL i, andStripData.mem_overlapL_finishputs the point at(len i - 3 lam / 2, rho / 2)in bothblockL iandsectorL (i + 1). The twoStripDataconstraints that make these work are exactly the two the structure advertises for the purpose:four_lam_lt_lenkeeps the frame position inside the block, andtwo_lam_lt_Rkeeps it inside the sector, since3 lam / 2 + rho / 2 < 2 lam < R.The chaining is then a finite induction along
chainL, and it does not need the wrap-around: connectedness of a union of connected sets only needs some spanning tree of the overlap graph, and the linear chain0, 1, …, m + 2is one. The blueprint's "the labels return consistently after one circuit" is a statement about the labelling, not about connectedness, and it isStrip.sideL_disjoint_sideR, already proved: it is what makessideLandsideRtwo sets rather than one.The collar is a neighbourhood, and removing the curve leaves exactly the two sides.
StripData.nbhd_diff_carrieris immediate from the two disjointness results ofStrip.lean. Openness ofnbhdis not:nbhdcontains the curve, so it has to be recognised as a union of open sets.StripData.nbhd_eqdoes that, rewriting it as the union of the vertex balls and the full edge tubes; the two inclusions areball_diff_carrier_subsetandtube_diff_carrier_subsetone way, and the covering of each edge by "near the first vertex, near the second vertex, or in the trimmed middle" the other way.
Blueprint #
Schoenflies.StripData.isConnected_sideL,.isConnected_sideR— "the union of all left pieces is connected; the same is true on the right", inside Lemma 1.8 (a).Schoenflies.StripData.nbhd_diff_carrier—N \ P = N_L ⊔ N_R, Lemma 1.8 (a).Schoenflies.StripData.collar— Lemma 1.8 (a) for a closed polygon, given the constants.
Producing the constants is exists_stripData, which lives elsewhere; every statement here is
for a given D : StripData P, exactly as in Schoenflies/Strip.lean.
Two frames at one edge #
Everything below needs the edge frame read from both ends: Strip.lean has the departure
end, and the overlap with the sector at the far vertex needs the arrival end.
The incoming ray at a vertex is a unit vector.
The two incident edges, as rays out of a vertex #
mem_edge_sub and mem_edge_pred_sub read a point of an incident edge as a multiple of a ray.
The converses are what says that a ball about a vertex minus the curve is covered by the two
sectors: a direction on one of the two rays is on the curve, not beside it.
A point of the incoming ray at distance at most the previous edge's length lies on that edge.
The overlaps #
The blueprint's "consecutive edge and vertex blocks overlap in a nonempty labelled half-strip".
Both witnesses sit at across-coordinate rho / 2, at along-coordinate 3 lam / 2 from the
vertex in question. The two hypotheses of StripData that were put there for this are
four_lam_lt_len — which gives 3 lam / 2 < len i - lam, so the point is inside the block —
and two_lam_lt_R together with rho < lam — which gives
3 lam / 2 + rho / 2 < 2 lam < R, so the point is inside the sector.
The along-coordinate of the witnesses clears the near trim.
The overlap at the departure vertex. The point at frame position (3 lam / 2, rho / 2)
of edge i lies both in the left block of that edge and in the left sector at i.
The overlap at the arrival vertex. The point at frame position
(len i - 3 lam / 2, rho / 2) of edge i lies both in the left block of that edge and in the
left sector at i + 1.
Chaining a cyclic family #
The union of the left pieces is connected because consecutive pieces overlap. This is a fact about any cyclically indexed family, and it is worth isolating: it is used once on the left and once on the right, and it is where the "cyclic" of the blueprint gets examined.
The point to notice is that the closing overlap F (last) ∩ F 0 is not used. A union of
connected sets is connected as soon as the overlap graph is connected, and the path
0 — 1 — ⋯ — N-1 already spans it; the extra edge back to 0 is a cycle, not a new vertex.
The blueprint's "the labels return consistently after one circuit" is therefore not needed
here: it is needed to know that the left label and the right label never collide, which is
StripData.sideL_disjoint_sideR, and that is already proved.
A cyclically indexed family of connected sets in which every member meets its successor has
connected union. Only the overlaps along the linear chain 0, 1, …, N - 1 are consumed.
The two sides are connected #
A piece is connected: its sector and its block overlap, at mem_overlapL_start.
The left side of the collar is connected.
The right side of the collar is connected.
The collar minus the curve is exactly the two sides #
nbhd was defined as sideL ∪ sideR ∪ carrier, so this is only the two disjointness
statements of Strip.lean read backwards.
Lemma 1.8 (a), the set equality. Removing the curve from the collar leaves exactly the
two labelled sides. With sideL_disjoint_sideR this is N \ P = N_L ⊔ N_R.
The collar is open #
nbhd contains the curve, so openness is not formal: it has to be exhibited as a union of open
sets. The two families are the vertex balls and the full edge tubes — the block of half-width
rho on both sides of the trimmed edge, core included. Each of the two is covered by
nbhd because its points off the curve are labelled (ball_diff_carrier_subset,
tube_diff_carrier_subset); conversely they cover nbhd, the only nontrivial part being that
they cover the curve itself, which is the three-way split of an edge into "within R of the
first vertex", "within R of the second", and "in the trimmed middle".
The full tube of edge i: the trimmed edge thickened by rho on both sides. It is the
union of the two blocks with the piece of the edge between them.
Instances For
A vertex ball minus the curve is covered by the two sectors at that vertex. A point of
the ball off the curve points in some direction from the vertex; by mem_ray_or_mem_arcCCW'
that direction is either one of the two incident rays — and then the point is on the incident
edge, because R_le_len says the sector does not run past the far end — or on one of the two
arcs, and then the point is in the corresponding sector.
Each edge is covered by the ball at its first vertex, the ball at its second, and its own
tube: lam < R leaves no gap in the middle.
The collar is the union of the vertex balls and the edge tubes. This is the presentation that makes it visibly open.
Lemma 1.8 (a) #
Two-sided polygonal strips, the closed case. Given the constants, the collar of a simple
closed polygon is an open neighbourhood of the curve whose complement in it is the disjoint
union of the two connected open local sides. This is Lemma 1.8 (a) of the blueprint, modulo
exists_stripData, which produces the constants.
The existential form of Lemma 1.8 (a): a simple closed polygonal curve for which the
constants exist has an open neighbourhood N with N \ P the disjoint union of two connected
open sets.