decideEnd function
AttachedEnd?
decideEnd(
- DraftDocument doc,
- List<
AttachedEnd> candidates, { - required DimKind kind,
- required Vector2 at,
- required Vector2 other,
- required Transform2 m,
The end a dimension stores for a point whose attach candidates are
given (spec 11 D10's "The choice among candidates", R-17; decisions 19
and 22), or null when there are none (the end is fixed).
at is the world point being decided, other the dimension's other end's
world point, kind the kind being committed and m the dimension group's
local-to-world transform. The measuring direction is
u = measuringDirection(kind, at, other, m) (D6): for aligned the pair's
direction, for horizontal and vertical the group's local x or y in world.
- The parallel measure: for each candidate wall
W, with world unit directiond_W(its start to its end, read throughdoc),σ_W = |u × d_W|, the sine of the angle between the wall andu. A degenerate wall (length ≤wallJoin.linear) has no direction and takesσ_W = 1, the least parallel. - The most parallel: keep the candidates with
σ_W ≤ min σ + dimAttach.angular: a band around the minimum, so the order is total (two walls meeting end to end in line are both kept). - The lowest wall handle.
- Face before centre, then the lower
k, then left before right. Within one wall only coincident points reach this step: a left-justified wall's right face is its centreline, so(k, right)is stored over(k, centre).
When it is decided is the callers' (decision 22), never this function's:
- the tool decides both ends at the commit (the third click), with the committed kind, from candidates gathered against the document as it is then;
- an end grip decides the dropped end only, at the drop, with the dimension's current kind and, for aligned, the other end's current world point; the other end keeps its stored reference;
- never a kind switch, a wall edit or a move: a stored reference changes only when a person re-picks that end.
Every candidate's wall is a wall of doc (the candidates are gathered
against it).
Implementation
AttachedEnd? decideEnd(DraftDocument doc, List<AttachedEnd> candidates,
{required DimKind kind,
required Vector2 at,
required Vector2 other,
required Transform2 m}) {
if (candidates.isEmpty) return null;
final u = measuringDirection(kind, at, other, m);
final sigma = <Handle, double>{};
var least = double.infinity;
for (final e in candidates) {
final s = sigma[e.wall] ??= _parallelMeasure(doc, e.wall, u);
if (s < least) least = s;
}
AttachedEnd? best;
for (final e in candidates) {
if (!(sigma[e.wall]! <= least + dimAttach.angular)) continue;
if (best == null || _before(e, best)) best = e;
}
return best;
}