PHY: 座標を親からの相対に統一し、回転中心パラメータを廃止

クラスター単位の移動・回転を親ノード1つの書き換えで済ませるため、
各ノードは親から見た変換 (x, y, rotation) を持つことにし、絶対座標は
保持しないことにした。回転軸は常に自分自身のローカル原点に固定し、
KLE の rotation_x / rotation_y に相当するパラメータは持たない。

あわせてスナップの基準系をローカル座標系と明記し、親の変換を受けない
w, h を Transform から分離した。KLE出力時の行のまとまりは未解決の問い
として未確認事項に立てた。

Journal: journal/2026-09-18-phy-coordinate-model.md

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MdLT5x5ka5y6CaWLeE3EKb
This commit is contained in:
2026-09-18 08:44:22 +09:00
co-authored by Claude Opus 5
parent 55243f626d
commit cd6a94f4f4
2 changed files with 131 additions and 24 deletions
+54 -24
View File
@@ -18,28 +18,44 @@ PHYレイヤーは、キースイッチやキーキャップ、その他周辺
ユニットサイズ(1Uが何mmか、x軸・y軸それぞれ)を規定。
ビジュアル表現として、内側へのオフセット位置及びオフセット距離(mm or U単位)・R(U単位)を規定。
### キーの座標
### 座標と回転
キーキャップの左上角をローカル原点とする。
座標単位はU。1Uのサイズは別途指定する。
回転中心はローカル原点からの相対座標で表す。グローバル
座標・回転角度は0.25U単位・15度単位でスナップするが正規化しない。
各ノードは、親ノードから見た相対的な配置を持つ。絶対座標は保持しない。
クラスター単位の移動・回転を親ノード1つの書き換えで済ませるため、相対座標を正本とする。
配置は「親の座標系で θ 回転してから (x, y) 平行移動」と定義する。
```txt
p_parent = Translate(x, y) · Rotate(θ) · p_child
```
この定義により、(x, y) は自分のローカル原点が親座標系のどこに来るかを表し、θ は自分の向きを表す。
回転軸は常に自分自身のローカル原点であり、パラメータとしては持たない。
キーもクラスターも同じ変換を持つため、キーごとに向きが異なる配置のためにクラスターを作る必要はない。
ローカル原点はキーキャップの左上角とする。座標単位はU。1Uのサイズはプロファイルで指定する。
座標・回転角度は、ローカル座標系で0.25U単位・15度単位でスナップするが正規化しない。
KLE JSONやPCB向けの出力は、階層を畳んで絶対座標に変換した導出物として生成する。
### キーのサイズ
0.25U単位でスナップするが正規化しない。
0.25U単位でスナップするが正規化しない。
サイズはローカルの値であり、親の変換を受けない。
### グルーピング
複数のキーを「クラスター」としてまとめて運用することができる。
クラスターのみにフォーカスして編集が可能。
クラスターごとの回転中心を設定できる。
クラスターの原点が、配下のノードの回転中心になる。
**内部処理での利用**:
- クラスターごとの一括編集・移動・回転
- 階層構造による管理(クラスターの入れ子構造)
- 編集時のフォーカス制御
- 回転中心を保存したい場合はクラスターにする(ノード自身は回転中心を持たないため)
**外部連携での扱い**:
@@ -51,28 +67,28 @@ PHYレイヤーは、キースイッチやキーキャップ、その他周辺
## 保存形式
キーごとに絶対座標を持つ。
全てのキー、またはキー及びクラスターをまとめたクラスターを配列として持つ
各ノードは親から見た変換を持つ。キーとクラスターを混在させた木構造として保持する。
```ts
type Position={
x:number,
y:number,
w:number,
h:number,
rx:number,
ry:number,
ra:number
type Transform = {
x: number, // 親座標系での位置
y: number,
rotation: number // 親座標系での回転角度(度)
}
type Key={
position:Position,
profile:Profile
type Size = {
w: number, // ローカル値。親の変換を受けない
h: number
}
type Cluster={
position:Position,
clusters:(Key[]|Cluster[])
type Key = {
transform: Transform,
size: Size,
profile: Profile
}
const keys:(Key|Cluster)[]=[]
type Cluster = {
transform: Transform,
children: (Key | Cluster)[]
}
const root: (Key | Cluster)[] = []
```
## 連携用出力形式
@@ -186,3 +202,17 @@ interface ClusterData {
3. **段階的移行**:既存のKLEユーザーが段階的に拡張機能を利用可能
4. **ツール間連携**:KLE標準形式での出力により、他のキーボード設計ツールとの相互運用性を確保
5. **データの軽量化**:KLE出力時に不要な情報を含めず、ファイルサイズを最小化
## 検討済み・非採用
- キーごとの絶対座標保持 (journal/2026-09-18-phy-coordinate-model.md)
- 相対座標と絶対座標の併記 (journal/2026-09-18-phy-coordinate-model.md)
- ノードごとの回転中心パラメータ (journal/2026-09-18-phy-coordinate-model.md)
## 未確認事項
### P-1 KLE JSONへ書き出した配置が行のまとまりを保てるか
- 位置づけ: 本文が前提にしているものではない。連携用出力形式の設計に関わる未解決の問い
- 現状の認識: 階層を畳んでKLEに読み込ませると行のまとまりが崩れる。他レイヤーの情報を使ってでも行ごとにまとめたいが、方法は未検討
- 格上げ条件: 回転を含むPHYデータをKLE JSONに変換してKLE本家に読み込ませ、rotation groupと行配列がどう再構成されるかを確認する