mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-06 07:29:42 +02:00
Bring the Ark0N/codeman-gesture-control repo in-tree as the codeman-gesture-control workspace package so the hand-tracking overlay can be developed in the Codeman repo. New npm run build:gesture bundles src/codeman/entry.ts into the served gesture-codeman.js; scripts/build.mjs reruns it on every production build. Source formatted to Codeman's prettier style. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
79 lines
1.6 KiB
TypeScript
79 lines
1.6 KiB
TypeScript
// MediaPipe hand landmark indices and the bone connections between them.
|
|
// See: https://developers.google.com/mediapipe/solutions/vision/hand_landmarker
|
|
//
|
|
// 21 landmarks per hand, each normalized to [0,1] in image space.
|
|
|
|
export const LANDMARK = {
|
|
WRIST: 0,
|
|
THUMB_CMC: 1,
|
|
THUMB_MCP: 2,
|
|
THUMB_IP: 3,
|
|
THUMB_TIP: 4,
|
|
INDEX_MCP: 5,
|
|
INDEX_PIP: 6,
|
|
INDEX_DIP: 7,
|
|
INDEX_TIP: 8,
|
|
MIDDLE_MCP: 9,
|
|
MIDDLE_PIP: 10,
|
|
MIDDLE_DIP: 11,
|
|
MIDDLE_TIP: 12,
|
|
RING_MCP: 13,
|
|
RING_PIP: 14,
|
|
RING_DIP: 15,
|
|
RING_TIP: 16,
|
|
PINKY_MCP: 17,
|
|
PINKY_PIP: 18,
|
|
PINKY_DIP: 19,
|
|
PINKY_TIP: 20,
|
|
} as const;
|
|
|
|
/** Pairs of landmark indices that form the hand skeleton, for overlay drawing. */
|
|
export const HAND_CONNECTIONS: ReadonlyArray<readonly [number, number]> = [
|
|
// Thumb
|
|
[0, 1],
|
|
[1, 2],
|
|
[2, 3],
|
|
[3, 4],
|
|
// Index
|
|
[0, 5],
|
|
[5, 6],
|
|
[6, 7],
|
|
[7, 8],
|
|
// Middle
|
|
[5, 9],
|
|
[9, 10],
|
|
[10, 11],
|
|
[11, 12],
|
|
// Ring
|
|
[9, 13],
|
|
[13, 14],
|
|
[14, 15],
|
|
[15, 16],
|
|
// Pinky
|
|
[13, 17],
|
|
[17, 18],
|
|
[18, 19],
|
|
[19, 20],
|
|
// Palm base
|
|
[0, 17],
|
|
];
|
|
|
|
export interface NormalizedLandmark {
|
|
x: number;
|
|
y: number;
|
|
z: number;
|
|
visibility?: number;
|
|
}
|
|
|
|
/** Euclidean distance between two normalized landmarks (x/y plane). */
|
|
export function dist2d(a: NormalizedLandmark, b: NormalizedLandmark): number {
|
|
const dx = a.x - b.x;
|
|
const dy = a.y - b.y;
|
|
return Math.hypot(dx, dy);
|
|
}
|
|
|
|
/** Midpoint of two normalized landmarks (x/y plane). */
|
|
export function midpoint(a: NormalizedLandmark, b: NormalizedLandmark): { x: number; y: number } {
|
|
return { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 };
|
|
}
|