mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-01 04:09:17 +00:00
fix: junction limits are honest at the boundaries (#331)
Six normative cuts, both mirrors symmetric (spec revision 3): - §2.1 node keys quantise to 1e-7 with the repository's canonicalisation formula (sign·floor(|v|·1e7+0.5)/1e7, -0 normalised) — toFixed(6) keys split one node into two on floating debris and produced two false П4 refusals on a legitimate resize (reproduced: -1e-8 vs 0). Node pairs within 2e-7 of each other (raw coordinates) are ONE node, and the node-to-wall incidence uses the same quantum. - §2.2 a ~0° wedge IS a violation: two rays leaving a node the same way are a duplicated or overlaid wall (a butt joint yields 180°, never 0°) — the worst degenerate case was invisible while 0.5° was refused. - §2.3/§2.4 the wall run is an iterative edge walk over the collinear component: no recursion (10 000 atoms answered, not RangeError), no silently dropped fork (the old .find lost every branch but the first), O(E) by construction, and collinearity is measured against the BASE segment's axis so an arc of 0.9°-per-atom pieces cannot pose as one wall. - §2.5 an exception while judging the CANDIDATE refuses the write with the junction.limit_check_failed toast (fail-closed, as the #278 guard); the baseline branch stays fail-open by design and the smoke proves the asymmetry by breaking only the second call of the deterministic pair. - §2.6 the python mirror narrows its except on the candidate side only: a genuine migration bug (TypeError) surfaces as an honest WS error, while a previous-side bug keeps the wide "no baseline" fallback — the two AC6 cases pin the asymmetry so swapped sides turn a unit red. Parity fixtures gain the new boundary classes (debris node, duplicate wall, collinear fork); four new mutants pin the filter, the key precision, the dropped branch and the fail-open hole. Issue: #331 User-Visible: yes
This commit is contained in:
@@ -2,6 +2,12 @@
|
||||
|
||||
## Unreleased
|
||||
|
||||
- The wall-junction checks are honest at the boundaries: false refusals on
|
||||
microscopic coordinate noise are gone, a wall duplicated along one line is
|
||||
now visible, very long walls no longer crash the check, and an internal
|
||||
check error refuses the write instead of waving it through
|
||||
([#331](https://github.com/Matysh/houseplan-card/issues/331)).
|
||||
|
||||
- Saving and resizing large plans no longer freezes Home Assistant: the
|
||||
junction-limit checks (#329) are orders of magnitude faster — the heavy
|
||||
part left the server's main loop, repeated work is cached
|
||||
|
||||
@@ -8,6 +8,12 @@
|
||||
|
||||
## Не выпущено
|
||||
|
||||
- Проверки стыков стен стали честными на границах: ложные отказы на
|
||||
микроскопических погрешностях координат устранены, дубль стены по одной
|
||||
линии теперь виден, очень длинные стены не роняют проверку, а внутренняя
|
||||
ошибка проверки больше не пропускает запись
|
||||
([#331](https://github.com/Matysh/houseplan-card/issues/331)).
|
||||
|
||||
- Сохранение и изменение размеров на больших планах больше не подвешивают
|
||||
Home Assistant: проверка ограничений стыков (#329) ускорена на порядки —
|
||||
тяжёлая часть ушла из основного цикла сервера, повторные вычисления
|
||||
|
||||
@@ -401,6 +401,10 @@ filler segment that compensates a thickness step is legal as long as the whole
|
||||
wall is longer than 20 cm. A T-joint (a wall end landing on the middle of
|
||||
another wall) is not forbidden by the distance rule.
|
||||
|
||||
If the check itself cannot run (an internal error), the change is not saved
|
||||
either — a "The junction check could not run" toast appears: the editor
|
||||
never waves a write through on faith.
|
||||
|
||||
The check runs on writes only. An already saved plan is never re-judged:
|
||||
migration, import and backup restore are never blocked, and an edit that does
|
||||
not touch the offending element passes as usual. The refusal appears where you
|
||||
|
||||
@@ -436,6 +436,10 @@ Undo оптимизации.
|
||||
стена целиком длиннее 20 см. Т-стык (конец стены упирается в середину чужой)
|
||||
правилом дистанции не запрещён.
|
||||
|
||||
Если проверку выполнить не удалось (внутренняя ошибка), изменение тоже не
|
||||
сохраняется — появляется тост «Проверку стыков выполнить не удалось»:
|
||||
редактор никогда не пропускает запись «на авось».
|
||||
|
||||
Проверка работает только на записи. Уже сохранённый план не переоценивается:
|
||||
миграция, импорт и восстановление из бэкапа не блокируются никогда, а правка,
|
||||
не трогающая нарушающий элемент, проходит как обычно. Отказ виден там, где вы
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"version": 1,
|
||||
"fixture": "synthetic-only",
|
||||
"chromium": "151.0.7922.34",
|
||||
"sourceFingerprint": "dbac4a84d0eb558e66066f5072363977ff4a78c0a032e6f2b9a5d0848cd20f0f",
|
||||
"sourceFingerprint": "7143ec154b3a4340ba7c23c47bc6f72fa68b81a03980a44b0eedc3f043f7305b",
|
||||
"captureScriptSha256": "ce2e9542fed9dade3085be87d16f69adb2ac8262893ad78ad966b1b9673f2983",
|
||||
"command": "npm run build && node demo/docs/capture.mjs",
|
||||
"scenarios": {
|
||||
@@ -14,7 +14,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "dbac4a84d0eb558e66066f5072363977ff4a78c0a032e6f2b9a5d0848cd20f0f",
|
||||
"sourceSha256": "7143ec154b3a4340ba7c23c47bc6f72fa68b81a03980a44b0eedc3f043f7305b",
|
||||
"imageSha256": "0ca982495a7749907c48ebbddfd089c54385a4347f79f64e94af2c5a8d5c03eb"
|
||||
},
|
||||
"view-touch": {
|
||||
@@ -25,7 +25,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "dbac4a84d0eb558e66066f5072363977ff4a78c0a032e6f2b9a5d0848cd20f0f",
|
||||
"sourceSha256": "7143ec154b3a4340ba7c23c47bc6f72fa68b81a03980a44b0eedc3f043f7305b",
|
||||
"imageSha256": "1c8e28ff34736b936ba7c9ec047d1da27aaf6fbb01411155f2d5c05282c02c41"
|
||||
},
|
||||
"space-create": {
|
||||
@@ -36,7 +36,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "dbac4a84d0eb558e66066f5072363977ff4a78c0a032e6f2b9a5d0848cd20f0f",
|
||||
"sourceSha256": "7143ec154b3a4340ba7c23c47bc6f72fa68b81a03980a44b0eedc3f043f7305b",
|
||||
"imageSha256": "a55b463055a565892ca139014e314a8f63fb5301c87fff2e48d7e69210fe9b6c"
|
||||
},
|
||||
"room-contour-close": {
|
||||
@@ -47,7 +47,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "dbac4a84d0eb558e66066f5072363977ff4a78c0a032e6f2b9a5d0848cd20f0f",
|
||||
"sourceSha256": "7143ec154b3a4340ba7c23c47bc6f72fa68b81a03980a44b0eedc3f043f7305b",
|
||||
"imageSha256": "dfad9a27371cfa397a3fd8dce7005f42d24649743f5322105ee894067d3a9f16"
|
||||
},
|
||||
"plan-context-tray": {
|
||||
@@ -58,7 +58,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "dbac4a84d0eb558e66066f5072363977ff4a78c0a032e6f2b9a5d0848cd20f0f",
|
||||
"sourceSha256": "7143ec154b3a4340ba7c23c47bc6f72fa68b81a03980a44b0eedc3f043f7305b",
|
||||
"imageSha256": "b75f348c632296da5c2fc142d53df613f757e1516acac315be50f5b4557729cc"
|
||||
},
|
||||
"device-editor": {
|
||||
@@ -69,7 +69,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "dbac4a84d0eb558e66066f5072363977ff4a78c0a032e6f2b9a5d0848cd20f0f",
|
||||
"sourceSha256": "7143ec154b3a4340ba7c23c47bc6f72fa68b81a03980a44b0eedc3f043f7305b",
|
||||
"imageSha256": "6b9cd281450e7782cff292f11efc58d227bedd0df86afc3be987feb2edec9dc3"
|
||||
},
|
||||
"device-display-preview": {
|
||||
@@ -80,7 +80,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "dbac4a84d0eb558e66066f5072363977ff4a78c0a032e6f2b9a5d0848cd20f0f",
|
||||
"sourceSha256": "7143ec154b3a4340ba7c23c47bc6f72fa68b81a03980a44b0eedc3f043f7305b",
|
||||
"imageSha256": "6f628abe6b89d7c4b352e6d73ac0b126526f6fdba5927bb774c5b884e484ca19"
|
||||
},
|
||||
"background-editor": {
|
||||
@@ -91,7 +91,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "dbac4a84d0eb558e66066f5072363977ff4a78c0a032e6f2b9a5d0848cd20f0f",
|
||||
"sourceSha256": "7143ec154b3a4340ba7c23c47bc6f72fa68b81a03980a44b0eedc3f043f7305b",
|
||||
"imageSha256": "a1d1a905f1410f73231d2ea5d1dfbd8ae79c2fe8b0a79cff87ebb977ac7a3103"
|
||||
},
|
||||
"room-card": {
|
||||
@@ -102,7 +102,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "dbac4a84d0eb558e66066f5072363977ff4a78c0a032e6f2b9a5d0848cd20f0f",
|
||||
"sourceSha256": "7143ec154b3a4340ba7c23c47bc6f72fa68b81a03980a44b0eedc3f043f7305b",
|
||||
"imageSha256": "48a5685039a5e0de2a28190d857b193c86e2e63606e3c7a8c40fc9d2b190da4e"
|
||||
},
|
||||
"device-info": {
|
||||
@@ -113,7 +113,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "dbac4a84d0eb558e66066f5072363977ff4a78c0a032e6f2b9a5d0848cd20f0f",
|
||||
"sourceSha256": "7143ec154b3a4340ba7c23c47bc6f72fa68b81a03980a44b0eedc3f043f7305b",
|
||||
"imageSha256": "29a342811aaedaebc54ba337792d60cb454a7cf4c3063b210f6c4bafe0a4d87b"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,6 +56,11 @@
|
||||
чужой стены остаётся T-стыком и валидно — правило про «почти-касание» без
|
||||
инцидентности). Порог абсолютный, в сантиметрах, и НЕ зависит от
|
||||
`cell_cm` пространства.
|
||||
- **Точность границ (#331):** ключ узла квантуется к 1e-7 формулой
|
||||
канонизации (`sign·floor(|v|·1e7+0.5)/1e7`, −0 → 0); пары точек ближе
|
||||
2e-7 (сырые координаты) — один узел, а не «почти-касание»; клин ровно 0°
|
||||
(дубль/наложение стены) — нарушение П1 с actual≈0; длина П3 меряется по
|
||||
коллинеарной (±1° к БАЗЕ прогона) компоненте связности одной толщины.
|
||||
- **П5. Просвет комнаты:** после вычета тел стен внутренняя область комнаты
|
||||
непуста и её площадь ≥ **25 см²**. Порог абсолютный и не зависит от
|
||||
`cell_cm`.
|
||||
|
||||
Reference in New Issue
Block a user