From 58c952f6a3eec8d659ad2ed08cf6c61069c73951 Mon Sep 17 00:00:00 2001 From: EwdErna Date: Sun, 20 Sep 2026 14:04:02 +0900 Subject: [PATCH] =?UTF-8?q?PHY:=20=E3=82=AF=E3=83=A9=E3=82=B9=E3=82=BF?= =?UTF-8?q?=E3=83=BC=E8=87=AA=E5=8B=95=E6=8E=A8=E5=AE=9A=E3=82=92=E3=82=84?= =?UTF-8?q?=E3=82=81=E3=80=81=E6=89=8B=E5=8B=95=E3=81=AE=E7=B5=84=E3=81=BF?= =?UTF-8?q?=E6=9B=BF=E3=81=88=E6=93=8D=E4=BD=9C=E3=82=92=E6=8C=81=E3=81=A4?= =?UTF-8?q?(P-3=E8=A7=A3=E6=B6=88)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 絶対配置を保ったままクラスターを作り、原点と基準角度を動かせる操作を持つ。 reparent と reframe の2演算に還元され、Transform が剛体変換なので結果は必ず表せる。 これに伴い、スナップは手作業入力時のみ・相対グリッドとし、計算結果には適用しない。 Journal: journal/2026-09-20-cluster-manual-grouping.md Co-Authored-By: Claude Opus 5 --- PHYレイヤー.md | 50 +++++++++++++++--- journal/2026-09-20-cluster-manual-grouping.md | 52 +++++++++++++++++++ 2 files changed, 94 insertions(+), 8 deletions(-) create mode 100644 journal/2026-09-20-cluster-manual-grouping.md diff --git a/PHYレイヤー.md b/PHYレイヤー.md index a7cd4d5..f59698e 100644 --- a/PHYレイヤー.md +++ b/PHYレイヤー.md @@ -37,7 +37,9 @@ p_parent = Translate(x, y) · Rotate(θ) · p_child ローカル原点はキーキャップの左上角とする。座標単位はU。1Uのサイズはプロファイルで指定する。 -座標・回転角度は、ローカル座標系で0.25U単位・15度単位でスナップするが正規化しない。 +座標・回転角度は、手作業での入力時に0.25U単位・15度単位でスナップするが正規化しない。 +グリッドは操作開始時の値を基準とする相対グリッドとし、ローカル原点を基準とした絶対グリッドにはしない。 +計算で得た値にはスナップを適用しない。組み替えで生じた非グリッド値を丸めると絶対配置が動くため。 KLE JSONやPCB向けの出力は、階層を畳んで絶対座標に変換した導出物として生成する。 @@ -121,6 +123,31 @@ LEDの配線はPHYが持たない。デイジーチェーンの順序はELC、RG - クラスター構造はBeyond KLEのデータにのみ存在する。外部形式へは階層を畳んだキー配置だけを出力する +### クラスターの組み替え + +クラスター構造は、配置を作ったあとから組み替える。KLE JSONから取り込んだ平坦なキー配置に +クラスターを与える経路がこれしかないため、エディタの基本操作として持つ。 +(エディタの操作仕様。将来ツール側のドキュメントへ移す) + +操作は次の2つの演算に還元される。どちらも対象の絶対配置を変えない。 + +- reparent: 親を変える。新しい親の変換を M_C、元の変換を M_i として `M_i' = M_C⁻¹ · M_i` +- reframe: 自分の変換を変え、配下を逆補正する。`M_i' = M_C'⁻¹ · M_C · M_i` + +| 操作 | 内部 | +|---|---| +| 選択をクラスター化 / 既存クラスターへの出し入れ / クラスター解除 | reparent | +| クラスターの原点移動・基準角度の変更 | reframe | +| クラスターの移動・回転(配下が追随する) | 自分の変換の書き換え | + +Transform は回転と平行移動だけを持つ剛体変換であり、合成と逆変換について閉じている。 +組み替えの結果は必ず Transform で表せる。サイズ・switchOffset・orientation はローカル値なので影響を受けない。 + +- 組み替えの対象は同一の親を持つノードに限る。複数の親にまたがる選択は組み替えできない +- クラスター化したときの初期値は、原点を選択の境界矩形の左上、基準角度を0とする。 + ただし選択したノード全部が同じ回転角度を持つ場合はその角度を基準角度に採り、境界矩形もその角度の座標系で取る +- 組み替えで生じた非グリッド値はそのまま保持する。クラスターを解除して親に戻ったノードも同じ + ## 保存形式 各ノードは親から見た変換を持つ。キーとクラスターを混在させた木構造として保持する。 @@ -236,11 +263,11 @@ Beyond KLEはスイッチの品種を持たないため、対応づける先が ## 検討済み・非採用 -- KLEのデカール・ゴースト・見た目属性を取り込み時に捨てる (journal/2026-09-19-kle-key-attributes.md) - スイッチのブランドをPHYで持つ (journal/2026-09-20-switch-terminal.md) - スイッチの品種・ソケット方式をPHYで持つ (journal/2026-09-20-switch-terminal-reversal.md) - LED専用ノード (journal/2026-09-20-led-node.md) - per-key LEDに座標を持たせる (journal/2026-09-20-led-node.md) +- KLE取り込み時のクラスター自動推定 (journal/2026-09-20-cluster-manual-grouping.md) ## 未確認事項 @@ -257,12 +284,6 @@ Beyond KLEはスイッチの品種を持たないため、対応づける先が - 現状の認識: 形状の許容誤差、ラベルの扱い、複数候補がある場合の決め方が未定 - 格上げ条件: 照合規則を決めたうえで、KLE本家でキーの移動・追加・削除をしたJSONを取り込み、意図どおりに対応づくことを確認する -### P-3 KLE JSON取り込み時のクラスター自動推定 - -- 位置づけ: 未解決の問い。PHYデータなしで過去のKLE JSONを取り込むとき、座標の近さや角度からクラスターを推定するか -- 現状の認識: 採用しない可能性が高い。ただし代わりに欲しい機能があり、それを思い出すきっかけとして残している -- 格上げ条件: 代わりの機能を定義し、この推定を採るか捨てるかをユーザーが決める - ### P-6 キーキャップの見た目情報を持つ層 - 位置づけ: 本文「見た目の属性は保持する。どの層で持つかは決まっていない」の未解決部分 @@ -286,3 +307,16 @@ Beyond KLEはスイッチの品種を持たないため、対応づける先が - 位置づけ: 本文「部品ノードは表裏を持たない」の残余 - 現状の認識: どちらの面に載るかはPCB設計ツールが決める情報なのでPHYには持たない。ただしエディタ上で裏面の部品を描き分けたくなる可能性があり、`@` 始まりの予約グループ名だけで表現できるかは未検証 - 格上げ条件: 予約グループ名による描画を実装し、表裏の描き分けが必要になるか、必要なら予約名で足りるかを確認する + +### P-13 reframeと通常の移動・回転をエディタ上でどう区別するか + +- 位置づけ: 本文「クラスターの組み替え」の残余。データモデル側は決まっており、操作系だけが未定 +- 現状の認識: クラスターへのフォーカス状態に紐づけ(中に入っている間は配下の絶対配置が変わらない)、 + そのうえで原点ハンドルと通常の移動・回転ハンドルを分ける案が有力。専用モードを設ける案もある +- 格上げ条件: 操作系をユーザーが決める + +### P-14 クラスター原点の吸着先 + +- 位置づけ: 未解決の問い。数値入力以外に、原点をどこへ吸着させるか +- 現状の認識: キーのローカル原点(左上角)・キー中心・境界矩形の角と中心が候補。相対グリッドとは別の機構になる +- 格上げ条件: 原点移動を実装し、吸着なしで足りるか、足りない場合どの候補が要るかを確認する diff --git a/journal/2026-09-20-cluster-manual-grouping.md b/journal/2026-09-20-cluster-manual-grouping.md new file mode 100644 index 0000000..bb58302 --- /dev/null +++ b/journal/2026-09-20-cluster-manual-grouping.md @@ -0,0 +1,52 @@ +# クラスター自動推定をやめ、手動の組み替え操作を持つ + +## 結論 + +KLE取り込み時のクラスター自動推定(P-3)は採らない。代わりに、絶対配置を保ったままクラスターを +作り・原点と基準角度を動かせる手動操作をエディタの基本機能として持つ。 + +自動推定が不要になった理由ではなく、そもそも手動操作が独立に必須だった、という結論。 +PHYレイヤー.md の既存記述が2箇所でこれを前提にしていた。 + +- 「回転中心を保存したい場合はクラスターにする」 — 後から原点を置く手段がなければ使えない +- 「照合できないキーは root 直下に新規キーとして置く。クラスターへの割り当てはユーザーが行う」 + +## 案の比較 + +| 案 | 過去のKLE資産 | 誤り | +|---|---|---| +| 自動推定 | 一発で階層が付く場合がある | 推定を外したときユーザーが直せない(直す手段=手動操作がないため) | +| 手動の組み替え | 選択してまとめる手数がかかる | ユーザーの意図がそのまま入るので誤りがない | +| 両方 | 同上 | 手動操作があれば推定の価値は初期値の提案に落ちる。初期値は小さく済む(下記) | + +「両方」を棄却したのではなく、手動操作を定義した時点で推定の取り分が +「クラスター化時に選択キーの共通角度を基準角度の初期値に採る」程度まで縮んだ。 +これは「どのキーをまとめるか」を機械が決めていないので、自動推定とは別物として本文に入れた。 + +## 2つの演算への還元 + +思いついた操作(グループ化・出し入れ・解除・原点移動・基準角度変更)は全部これで書ける。 + +- reparent: `M_i' = M_C⁻¹ · M_i` +- reframe: `M_i' = M_C'⁻¹ · M_C · M_i` + +Transform が回転+平行移動のみ = 剛体変換の群なので、合成と逆変換について閉じている。 +せん断・拡縮が出てこないので、結果は必ず Transform で表せる。ここが成立しなければ +「絶対座標を変えないまま」は近似になっていた。 + +Size / switchOffset / orientation はローカル値で親の変換を受けない定義なので、影響を受けない。 + +## スナップとの衝突 + +基準角度を15度の倍数でない値にすると、配下の平行移動成分に `R(-θ)` が掛かって非グリッド値になる。 +ここを丸めると絶対配置が動く = 機能の目的が崩れる。よって2つ決めた。 + +- スナップは手作業の入力時のみ。計算結果には適用しない +- グリッドは操作開始時の値を基準とする相対グリッド。ローカル原点基準の絶対グリッドにしない + (非グリッド値を持つキーを後から掴んだとき、絶対配置が勝手に動くのを防ぐ) + +## 浮動小数の累積(実装時の注意、本文には書かない) + +原点・角度の調整を繰り返すと `M_C'⁻¹ · M_C` の合成が積み重なる。 +対話操作の間は操作開始時の絶対座標スナップショットを基準に relative を再計算すれば、 +誤差は1操作ぶんに収まる。相対座標が正本であることとは矛盾しない(セッション中の作業用の値)。