クラスター単位の移動・回転を親ノード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
219 lines
7.9 KiB
Markdown
219 lines
7.9 KiB
Markdown
# PHYレイヤー
|
||
|
||
## 概要
|
||
|
||
PHYレイヤーは、キースイッチやキーキャップ、その他周辺部品の物理的な配置に関する情報を提供する。
|
||
付加的な情報として、matrix情報(ELCレイヤー)や入力キー情報(MAP/IMEレイヤー)を含ませることができるが、必須ではない。
|
||
|
||
## 構造
|
||
|
||
### キースイッチ/キーキャップの配置
|
||
|
||
各キーはスイッチ・キャップの情報を統合された状態で持ち、キャップの位置・サイズからスイッチ座標を特定する。
|
||
以下、単に「キー」と呼ぶ場合、キーキャップの位置・サイズを表すオブジェクトをさすこととする。
|
||
|
||
### プロファイル設定
|
||
|
||
1ファイル内に複数のプロファイルを持たせることができる。
|
||
ユニットサイズ(1Uが何mmか、x軸・y軸それぞれ)を規定。
|
||
ビジュアル表現として、内側へのオフセット位置及びオフセット距離(mm or U単位)・R(U単位)を規定。
|
||
|
||
### 座標と回転
|
||
|
||
各ノードは、親ノードから見た相対的な配置を持つ。絶対座標は保持しない。
|
||
クラスター単位の移動・回転を親ノード1つの書き換えで済ませるため、相対座標を正本とする。
|
||
|
||
配置は「親の座標系で θ 回転してから (x, y) 平行移動」と定義する。
|
||
|
||
```txt
|
||
p_parent = Translate(x, y) · Rotate(θ) · p_child
|
||
```
|
||
|
||
この定義により、(x, y) は自分のローカル原点が親座標系のどこに来るかを表し、θ は自分の向きを表す。
|
||
回転軸は常に自分自身のローカル原点であり、パラメータとしては持たない。
|
||
キーもクラスターも同じ変換を持つため、キーごとに向きが異なる配置のためにクラスターを作る必要はない。
|
||
|
||
ローカル原点はキーキャップの左上角とする。座標単位はU。1Uのサイズはプロファイルで指定する。
|
||
|
||
座標・回転角度は、ローカル座標系で0.25U単位・15度単位でスナップするが正規化しない。
|
||
|
||
KLE JSONやPCB向けの出力は、階層を畳んで絶対座標に変換した導出物として生成する。
|
||
|
||
### キーのサイズ
|
||
|
||
0.25U単位でスナップするが正規化しない。
|
||
サイズはローカルの値であり、親の変換を受けない。
|
||
|
||
### グルーピング
|
||
|
||
複数のキーを「クラスター」としてまとめて運用することができる。
|
||
クラスターのみにフォーカスして編集が可能。
|
||
クラスターの原点が、配下のノードの回転中心になる。
|
||
|
||
**内部処理での利用**:
|
||
|
||
- クラスターごとの一括編集・移動・回転
|
||
- 階層構造による管理(クラスターの入れ子構造)
|
||
- 編集時のフォーカス制御
|
||
- 回転中心を保存したい場合はクラスターにする(ノード自身は回転中心を持たないため)
|
||
|
||
**外部連携での扱い**:
|
||
|
||
- KLE JSON出力時は、個別のキー配置のみを出力(クラスター情報は含めない)
|
||
- 別途クラスター情報JSONとして構造を保存
|
||
- キーIDによる紐づけで関連性を管理
|
||
|
||
### 何かある?
|
||
|
||
## 保存形式
|
||
|
||
各ノードは親から見た変換を持つ。キーとクラスターを混在させた木構造として保持する。
|
||
|
||
```ts
|
||
type Transform = {
|
||
x: number, // 親座標系での位置
|
||
y: number,
|
||
rotation: number // 親座標系での回転角度(度)
|
||
}
|
||
type Size = {
|
||
w: number, // ローカル値。親の変換を受けない
|
||
h: number
|
||
}
|
||
type Key = {
|
||
transform: Transform,
|
||
size: Size,
|
||
profile: Profile
|
||
}
|
||
type Cluster = {
|
||
transform: Transform,
|
||
children: (Key | Cluster)[]
|
||
}
|
||
const root: (Key | Cluster)[] = []
|
||
```
|
||
|
||
## 連携用出力形式
|
||
|
||
### 設計方針
|
||
|
||
KLE向けの出力は既存のKLE JSON形式を維持し、クラスター情報は別のJSONファイルとして出力する。
|
||
両者の紐づけは、KLEのlabel部分に埋め込むユニークIDを使用する。
|
||
|
||
### KLE JSON出力
|
||
|
||
標準的なKLE JSON形式で出力。各キーのlabelにはユニークIDを含める。
|
||
|
||
```ts
|
||
type ConfigObject = {
|
||
x?: number,
|
||
y?: number,
|
||
w?: number,
|
||
h?: number,
|
||
x2?: number,
|
||
y2?: number,
|
||
w2?: number,
|
||
h2?: number,
|
||
rx?: number,
|
||
ry?: number,
|
||
ra?: number,
|
||
l?: boolean,
|
||
n?: boolean,
|
||
d?: boolean,
|
||
c?: string,
|
||
t?: string,
|
||
g?: boolean,
|
||
a?: number,
|
||
f?: number,
|
||
f2?: number,
|
||
p?: string,
|
||
s?: string
|
||
}
|
||
|
||
type KeyLabel = string // ユニークID + 表示用ラベルを含む
|
||
const kleData = (ConfigObject | KeyLabel)[][]
|
||
```
|
||
|
||
### クラスター情報JSON
|
||
|
||
キーのクラスター構造を管理する別ファイル。
|
||
|
||
```ts
|
||
interface ClusterInfo {
|
||
id: string, // クラスターのユニークID
|
||
name?: string, // 表示用クラスター名
|
||
position?: Position, // クラスター自体の位置・回転情報
|
||
keyIds: string[], // 所属するキーのIDリスト
|
||
subClusters?: string[] // 子クラスターのIDリスト(ネスト構造用)
|
||
}
|
||
|
||
interface ClusterData {
|
||
version: string,
|
||
profiles: Profile[], // プロファイル定義
|
||
keys: { // キーID -> 追加情報のマップ
|
||
[keyId: string]: {
|
||
originalLabel?: string, // KLEのlabelから抽出した表示用文字列
|
||
matrix?: MatrixPosition, // matrix情報(オプション)
|
||
mapping?: KeyMapping // キーマッピング情報(オプション)
|
||
}
|
||
},
|
||
clusters: ClusterInfo[] // クラスター構造定義
|
||
}
|
||
```
|
||
|
||
### 出力例
|
||
|
||
#### keyboard.json (KLE形式)
|
||
|
||
```json
|
||
[
|
||
["key-001\nQ", "key-002\nW", "key-003\nE"],
|
||
["key-004\nA", "key-005\nS", "key-006\nD"]
|
||
]
|
||
```
|
||
|
||
#### keyboard-clusters.json
|
||
|
||
```json
|
||
{
|
||
"version": "1.0.0",
|
||
"keys": {
|
||
"key-001": { "originalLabel": "Q", "matrix": [0, 0] },
|
||
"key-002": { "originalLabel": "W", "matrix": [0, 1] },
|
||
"key-003": { "originalLabel": "E", "matrix": [0, 2] },
|
||
"key-004": { "originalLabel": "A", "matrix": [1, 0] },
|
||
"key-005": { "originalLabel": "S", "matrix": [1, 1] },
|
||
"key-006": { "originalLabel": "D", "matrix": [1, 2] }
|
||
},
|
||
"clusters": [
|
||
{
|
||
"id": "cluster-alpha",
|
||
"name": "英字キー",
|
||
"keyIds": ["key-001", "key-002", "key-003", "key-004", "key-005", "key-006"]
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
### 分離設計のメリット
|
||
|
||
この設計により以下の利点が得られる:
|
||
|
||
1. **KLE互換性の維持**:既存のKLE関連ツールとの完全な互換性を保持
|
||
2. **柔軟な拡張性**:クラスター情報を独立して管理・拡張可能
|
||
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と行配列がどう再構成されるかを確認する
|