trimSeparator function
- Vector2 a,
- Vector2 b,
- RoomInputs inputs, {
- required bool objectSnap,
The separator a person draws from a to b, in world, as it is stored
(spec 10 D20, R-21; Ruling 10-9): the one function the Separator tool and
the separator grips call.
With objectSnap (F3), an end inside a wall's uncut band (inputs'
closed inputs) moves back along the segment to the first point where the
segment, walked from its other end as placed, enters that band: the
stored end lies on the face, to rounding, so it joins the face (D5) and
the separator does not draw into the wall. An end in open space stays
where it was put. An end inside several bands (walls that overlap) stops
at the first of their faces the walk meets. When the walk crosses into
another band first and passes into the end's band through a joint (a
mitre), the trimmed end lies in that other band: it is trimmed again,
to where the walk enters that one, and so on while it lies in, or within
roomTrace.linear of, a band not yet trimmed to (a mitre's end lies on
the edge the two bands share, where the crossing number may count it
out of either). Each round moves the end toward the other end along
the segment and uses up at least one band, so it stops. Both ends inside
one band: null.
Without objectSnap, (a, b) as placed: trimming is object snapping,
and an end left inside a band still splits the face correctly.
Either way, a result no longer than roomTrace.linear is null: it
would be a degenerate separator (D3).
Implementation
(Vector2, Vector2)? trimSeparator(Vector2 a, Vector2 b, RoomInputs inputs,
{required bool objectSnap}) {
var s = a, e = b;
if (objectSnap) {
final inA = _bandsHolding(a, inputs);
final inB = _bandsHolding(b, inputs);
if (inA.any(inB.contains)) return null;
if (inB.isNotEmpty) e = _trimmed(a, b, inB, inputs);
if (inA.isNotEmpty) s = _trimmed(b, a, inA, inputs);
}
if (!((e - s).length > roomTrace.linear)) return null;
return (s, e);
}