From 1ecd26713882e11760daed80003632d7e8778ba2 Mon Sep 17 00:00:00 2001 From: Codex Date: Fri, 21 Aug 2026 11:55:51 +0300 Subject: [PATCH] docs: a room junction is a side, not just a corner (#229 r2 M1) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The tolerance fix in r2 named the room's nearest polygon vertex as the point of contact, which silently excluded the T-junction — a partition meeting the middle of a room wall. That is a documented product case (141-wall-junctions §13.1) and the code already measures distance to the edge, not the vertex (distToSegment over roomEdges). Merging would have run straight through a legitimate node. AC2 now proves the room case with a T-junction into the middle of a long side, and a mutant restores the vertex-only search. Issue: #229 User-Visible: no --- docs/specs/229-merge-collinear-partitions.md | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/docs/specs/229-merge-collinear-partitions.md b/docs/specs/229-merge-collinear-partitions.md index 59025b00..20dbae8f 100644 --- a/docs/specs/229-merge-collinear-partitions.md +++ b/docs/specs/229-merge-collinear-partitions.md @@ -116,8 +116,17 @@ run of one thickness», оптимизатор её вызывает (`plan-opti проверяется совпадение концов самих перегородок (§8.3). Отдельного допуска для ребра комнаты, колонны или черновика нет: иначе один и тот же зазор считался бы стыком в одном случае и не считался в другом, а AC2 перестал бы быть однозначным. -Точка стыка берётся у ребра комнаты — ближайшая вершина полигона, у колонны — -её центр, у черновика — конец сохранённого контура. +Точка стыка берётся у ребра комнаты — **ближайшая точка на любой стороне +полигона**, а не только его вершина; у колонны — её центр, у черновика — конец +сохранённого контура. + +Именно сторона, а не вершина: T-стык перегородки к середине комнатной стены — +штатный случай продукта (`docs/specs/141-wall-junctions.md` §13.1 прямо называет +примыкание «к середине существующей wall/partition»), и такой узел обязан +пережить слияние. Примитив для этого в коде уже есть — `distToSegment` по +рёбрам комнаты (`plan-snap-overlay.ts:313`), считающий расстояние до отрезка. +Ревизия r3: прежняя редакция говорила «ближайшая вершина полигона» и пропускала +ровно этот случай (находка M1 ревью r2). ### 8.3. Допуски @@ -219,7 +228,9 @@ plan-only export, merge и оптимизация сохраняли согла с крайними точками цепочки. **Доказательство:** `unit` + `smoke`. 2. **AC2 — узел с причиной остаётся.** Слияния не происходит, если на общем конце есть третья перегородка, ребро комнаты, колонна или конец черновика — четыре - отдельных случая. **Доказательство:** `unit`. + отдельных случая. Случай «ребро комнаты» проверяется **T-стыком к середине + стороны**, а не только к её углу: тест с примыканием в середину длинного ребра + красный, если реализация ищет лишь вершины полигона. **Доказательство:** `unit`. 3. **AC3 — проём не двигается, в обоих представлениях.** Перегородка с дверью посередине сращивается с соседней; координаты центра, полученные через `resolvePartitionOpening`, до и после совпадают, `host.id` указывает на @@ -265,6 +276,7 @@ plan-only export, merge и оптимизация сохраняли согла | `partition-merge-disabled` | не вызывать слияние в `_finishWallChain` | смок AC1 | | `partition-merge-ignores-thickness` | сращивать при разном `cm` | юнит AC4 | | `partition-merge-ignores-junction` | сращивать через примыкание третьей стены | юнит AC2 | +| `junction-checks-room-vertices-only` | искать примыкание комнаты только по вершинам полигона | юнит AC2 (T-стык) | | `partition-merge-keeps-relative-t` | не пересчитывать `host.t` | юнит AC3 | | `partition-merge-skips-materialization` | не обновлять `x/y/angle` проёма | юнит AC3 | | `chain-merge-sweeps-whole-space` | сращивать все перегородки пространства, а не компоненту цепочки | юнит AC8 |