fix: cap junction mitres at the visual limit and drop foreign-sector pair patches (#309)

Вылет mitre ограничен VISUAL_MITRE_LIMIT = 1.5·max(h): длиннее — плоская
фаска перпендикулярно направлению вершины (chamferApex), в парных патчах и
в веерах узлов. Узлы ≥3 канонических лучей закрываются веерами
junctionNodeGeometry прямо в linearWallJoinPatches: парный патч живёт в
секторе, противоположном своей паре, и красил ступень поверх тонких полос
(крест 15/15/30/30 из отчёта владельца). Прямые углы (вылет 1.41h)
байтово прежние. Механизм #249 (MULTI_WALL_JOIN_LIMIT,
multiWallBevelCutsAt, mitre контуров комнат) не тронут.

Юниты формы на фикстуре трёх узлов владельца + контрактный детектор дыр;
4 новых мутанта, краснота каждого проверена исполнением. Матрица golden 46:
три новые сцены junction-309-{step,spike,hump}-dark.

Issue: #309
User-Visible: yes
This commit is contained in:
Codex
2026-08-25 21:50:28 +03:00
parent 787891c4e7
commit 101cf70952
12 changed files with 668 additions and 271 deletions
+7
View File
@@ -2,6 +2,13 @@
## Unreleased
- Wall junctions no longer sprout teeth: a mitre apex is limited to 1.5
half-depths and anything longer is closed with a flat drafting chamfer, so
acute pairs lose their tails, thick multi-wall nodes lose their peaks, and
mixed-thickness crosses no longer show a step in a foreign quadrant. Square
corners are untouched
([#309](https://github.com/Matysh/houseplan-card/issues/309)).
- The active wall chain keeps its axis and node markers visible on already
placed segments while drawing. The chain ink now paints above the wall
masonry (and below the snap overlay), so each click no longer buries the
+6
View File
@@ -8,6 +8,12 @@
## Не выпущено
- Стыковочные узлы больше не выпускают зубцы: вылет mitre ограничен
1.5 полутолщины, всё длиннее закрывается плоской чертёжной фаской — у
острых пар исчезают хвосты, у толстых многолучевых узлов пики, а кресты
смешанных толщин теряют ступеньку в чужом квадранте. Прямые углы не
изменились ([#309](https://github.com/Matysh/houseplan-card/issues/309)).
- Во время рисования цепочки стен осевая линия и узлы остаются видимыми на уже
поставленных сегментах. Разметка цепочки теперь рисуется поверх кладки стен
(и под снап-оверлеем), поэтому каждый клик больше не прячет жёлтую ось под
+15
View File
@@ -203,6 +203,21 @@ bound» is machine-checked by `junctionContractHoles` in tests and the
`smoke_junction_holes` wiring probe. Degenerate zero-area rings left by
coincident chords are dropped.
**Visual mitre limit (#309, owner decision 2026-08-25).** A mitre apex may
protrude at most `VISUAL_MITRE_LIMIT = 1.5` maximal half-depths from the node
(a square corner of equal depths peaks at ~1.41·h, so right and obtuse
corners are byte-identical); a longer apex is closed with a flat chamfer
perpendicular to the apex direction at the limit (`chamferApex`). The rule
applies to both the junction fans and the pair patches of
`linearWallJoinPatches`; `MITRE_LIMIT = 4` survives only as the sanity bound
for candidate construction. At a node of three or more canonical rays the
pair patches are not built at all: a pair patch lives in the sector OPPOSITE
its pair and painted a step over the thinner strips owning that sector (the
15/15/30/30 cross of the owner report) — such nodes are closed with the same
sector fans via a local multi-wall node map inside `linearWallJoinPatches`.
The #249 machinery (`MULTI_WALL_JOIN_LIMIT = 1.25`, `multiWallBevelCutsAt`,
room-contour mitres) is untouched.
**Hatch density is physical (#230).** The pattern step is a distance on the
plan, not a count of coordinate units: `wallHatchStepUnits(cellCm)` returns
`8 × (5 / cell_cm)`, which is 9.6 cm at every grid scale and exactly the
+11 -11
View File
@@ -2,7 +2,7 @@
"version": 1,
"fixture": "synthetic-only",
"chromium": "151.0.7922.34",
"sourceFingerprint": "e9ccc3f9aecc3ce4de775233b9e31aedca19c8a474d9839d96a82ebd79d0f272",
"sourceFingerprint": "81255e1bea5fc85e11741baf7a296d033ec81cce05dede922d60924597ea605a",
"captureScriptSha256": "ce2e9542fed9dade3085be87d16f69adb2ac8262893ad78ad966b1b9673f2983",
"command": "npm run build && node demo/docs/capture.mjs",
"scenarios": {
@@ -14,7 +14,7 @@
},
"theme": "dark",
"language": "en",
"sourceSha256": "e9ccc3f9aecc3ce4de775233b9e31aedca19c8a474d9839d96a82ebd79d0f272",
"sourceSha256": "81255e1bea5fc85e11741baf7a296d033ec81cce05dede922d60924597ea605a",
"imageSha256": "0ca982495a7749907c48ebbddfd089c54385a4347f79f64e94af2c5a8d5c03eb"
},
"view-touch": {
@@ -25,7 +25,7 @@
},
"theme": "dark",
"language": "en",
"sourceSha256": "e9ccc3f9aecc3ce4de775233b9e31aedca19c8a474d9839d96a82ebd79d0f272",
"sourceSha256": "81255e1bea5fc85e11741baf7a296d033ec81cce05dede922d60924597ea605a",
"imageSha256": "1c8e28ff34736b936ba7c9ec047d1da27aaf6fbb01411155f2d5c05282c02c41"
},
"space-create": {
@@ -36,7 +36,7 @@
},
"theme": "dark",
"language": "en",
"sourceSha256": "e9ccc3f9aecc3ce4de775233b9e31aedca19c8a474d9839d96a82ebd79d0f272",
"sourceSha256": "81255e1bea5fc85e11741baf7a296d033ec81cce05dede922d60924597ea605a",
"imageSha256": "329750c81a7a958c4fd105b2c80f85dce55ed87df9ddf0ea08084e4428e85f04"
},
"room-contour-close": {
@@ -47,7 +47,7 @@
},
"theme": "dark",
"language": "en",
"sourceSha256": "e9ccc3f9aecc3ce4de775233b9e31aedca19c8a474d9839d96a82ebd79d0f272",
"sourceSha256": "81255e1bea5fc85e11741baf7a296d033ec81cce05dede922d60924597ea605a",
"imageSha256": "ff2e903e548423aa0aa52680e20b8ad951c704e01130cb4b180222015a241276"
},
"plan-context-tray": {
@@ -58,7 +58,7 @@
},
"theme": "dark",
"language": "en",
"sourceSha256": "e9ccc3f9aecc3ce4de775233b9e31aedca19c8a474d9839d96a82ebd79d0f272",
"sourceSha256": "81255e1bea5fc85e11741baf7a296d033ec81cce05dede922d60924597ea605a",
"imageSha256": "ff55925f079411023442e7e7dd5ed528c331aaa3fd3fc2fbbf3b1aaf34a85718"
},
"device-editor": {
@@ -69,7 +69,7 @@
},
"theme": "dark",
"language": "en",
"sourceSha256": "e9ccc3f9aecc3ce4de775233b9e31aedca19c8a474d9839d96a82ebd79d0f272",
"sourceSha256": "81255e1bea5fc85e11741baf7a296d033ec81cce05dede922d60924597ea605a",
"imageSha256": "6b9cd281450e7782cff292f11efc58d227bedd0df86afc3be987feb2edec9dc3"
},
"device-display-preview": {
@@ -80,7 +80,7 @@
},
"theme": "dark",
"language": "en",
"sourceSha256": "e9ccc3f9aecc3ce4de775233b9e31aedca19c8a474d9839d96a82ebd79d0f272",
"sourceSha256": "81255e1bea5fc85e11741baf7a296d033ec81cce05dede922d60924597ea605a",
"imageSha256": "6f628abe6b89d7c4b352e6d73ac0b126526f6fdba5927bb774c5b884e484ca19"
},
"background-editor": {
@@ -91,7 +91,7 @@
},
"theme": "dark",
"language": "en",
"sourceSha256": "e9ccc3f9aecc3ce4de775233b9e31aedca19c8a474d9839d96a82ebd79d0f272",
"sourceSha256": "81255e1bea5fc85e11741baf7a296d033ec81cce05dede922d60924597ea605a",
"imageSha256": "a1d1a905f1410f73231d2ea5d1dfbd8ae79c2fe8b0a79cff87ebb977ac7a3103"
},
"room-card": {
@@ -102,7 +102,7 @@
},
"theme": "dark",
"language": "en",
"sourceSha256": "e9ccc3f9aecc3ce4de775233b9e31aedca19c8a474d9839d96a82ebd79d0f272",
"sourceSha256": "81255e1bea5fc85e11741baf7a296d033ec81cce05dede922d60924597ea605a",
"imageSha256": "48a5685039a5e0de2a28190d857b193c86e2e63606e3c7a8c40fc9d2b190da4e"
},
"device-info": {
@@ -113,7 +113,7 @@
},
"theme": "dark",
"language": "en",
"sourceSha256": "e9ccc3f9aecc3ce4de775233b9e31aedca19c8a474d9839d96a82ebd79d0f272",
"sourceSha256": "81255e1bea5fc85e11741baf7a296d033ec81cce05dede922d60924597ea605a",
"imageSha256": "29a342811aaedaebc54ba337792d60cb454a7cf4c3063b210f6c4bafe0a4d87b"
}
}