d8a80f6272
이름만 다른(표기 변형) [[위키링크]]를 대상 문서의 canonical 제목으로 치환해 끊겼던 1,200개 링크를 연결. 제목/파일명 정규화 일치만 적용하고 별칭 매칭은 과병합 위험으로 제외(애매성 가드). 원본은 _link_reconcile_backup/ 에 백업. 도구: Datacollect/scripts/link_reconcile_apply.mjs Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
6.6 KiB
6.6 KiB
id, title, category, status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, verification_status, tags, raw_sources, last_reinforced, github_commit, tech_stack
| id | title | category | status | canonical_id | aliases | duplicate_of | source_trust_level | confidence_score | verification_status | tags | raw_sources | last_reinforced | github_commit | tech_stack | |||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| wiki-2026-0508-안구-운동-기능-oculomotor-functions | 안구 운동 기능 (Oculomotor functions) | 10_Wiki/Topics | verified | self |
|
none | B | 0.85 | applied |
|
2026-05-10 | pending |
|
안구 운동 기능 (Oculomotor functions)
매 한 줄
"매 시선은 의도다". 사람의 안구 움직임 (saccade, smooth pursuit, fixation, vergence)은 attention과 intent의 신호 — HCI architecture에서 input modality, foveated rendering의 trigger, 그리고 accessibility의 핵심 channel. 2026 Apple Vision Pro·Quest 3·PSVR 2가 모두 eye tracking을 표준화하면서 architecture-level 시스템 component로 격상.
매 핵심
매 4 가지 안구 운동
- Saccade: 빠른 도약 (200-300°/s), 도중에는 시각 정보 suppress (saccadic suppression).
- Smooth pursuit: 움직이는 target 추적, 대상 없이 의식적으로 만들 수 없음.
- Fixation: 한 점 응시 (200-300ms 평균), micro-tremor 포함.
- Vergence: 양안의 거리 조절 — depth/3D UI에서 핵심.
매 architecture 역할
- Input: gaze + dwell, gaze + pinch (Vision Pro 모델). 정확도 ~1°.
- Foveated rendering: gaze 주변 high-res, 주변부 low-res → GPU 50-70% 절약.
- Attention metric: heatmap 기반 UX 검증, A/B test의 implicit signal.
- Accessibility: ALS 등 운동 장애 사용자의 통신 channel.
매 응용
- VR/AR: foveated rendering, 자연스러운 selection.
- Web analytics: heatmap (Hotjar, Microsoft Clarity).
- 자동차 HMI: 운전자 attention 모니터링 (Tesla driver-facing camera, Cadillac Super Cruise).
- 의료: 신경학적 진단 (saccade latency = Parkinson 지표).
💻 패턴
WebXR로 gaze ray 얻기 (Vision Pro Safari)
// XRSession with eye-tracking feature
const session = await navigator.xr!.requestSession('immersive-vr', {
requiredFeatures: ['hand-tracking', 'eye-tracking'],
});
session.requestAnimationFrame(function frame(_t, xrFrame) {
const referenceSpace = /* … */;
for (const source of xrFrame.session.inputSources) {
if (source.targetRayMode === 'gaze') {
const pose = xrFrame.getPose(source.targetRaySpace, referenceSpace);
if (pose) handleGazeRay(pose.transform);
}
}
session.requestAnimationFrame(frame);
});
Dwell-time selection
class GazeDwellSelector {
private hovered: Element | null = null;
private since = 0;
constructor(private readonly thresholdMs = 800) {}
update(target: Element | null, now: number) {
if (target !== this.hovered) {
this.hovered = target; this.since = now;
target?.dispatchEvent(new CustomEvent('gazeenter'));
return;
}
if (target && now - this.since >= this.thresholdMs) {
target.dispatchEvent(new CustomEvent('gazeselect'));
this.since = Number.POSITIVE_INFINITY; // 한 번만 fire
}
}
}
Fixation detection (I-DT algorithm)
// I-DT: dispersion-threshold identification
type Sample = { x: number; y: number; t: number };
export function detectFixations(
samples: Sample[],
windowMs = 100,
dispersionDeg = 1.0,
): Array<{ start: number; end: number; cx: number; cy: number }> {
const out: any[] = [];
let i = 0;
while (i < samples.length) {
let j = i + 1;
while (j < samples.length && samples[j].t - samples[i].t < windowMs) j++;
const win = samples.slice(i, j);
const xs = win.map(s => s.x), ys = win.map(s => s.y);
const disp = (Math.max(...xs) - Math.min(...xs))
+ (Math.max(...ys) - Math.min(...ys));
if (disp < dispersionDeg) {
// extend
while (j < samples.length) {
const x2 = [...xs, samples[j].x], y2 = [...ys, samples[j].y];
const d = (Math.max(...x2) - Math.min(...x2))
+ (Math.max(...y2) - Math.min(...y2));
if (d >= dispersionDeg) break;
xs.push(samples[j].x); ys.push(samples[j].y); j++;
}
out.push({
start: samples[i].t, end: samples[j - 1].t,
cx: avg(xs), cy: avg(ys),
});
}
i = j;
}
return out;
}
const avg = (xs: number[]) => xs.reduce((a, b) => a + b, 0) / xs.length;
Foveated rendering hint (WebGPU)
// 2026 WebGPU에서 variable rate shading via gaze
const gaze = getGazeNDC(); // [-1,1]^2
device.queue.writeBuffer(uniformBuffer, 0, new Float32Array([
gaze.x, gaze.y, /*innerRadius*/ 0.15, /*outerRadius*/ 0.45,
]));
// fragment shader: distance(uv, gaze) > outer ⇒ discard 75% samples
Saccade 중 UI 변화 (change blindness 활용)
// saccade 검출 시 다음 frame에 layout 변경 → 사용자가 인지 못함
function onSaccadeStart(cb: () => void) {
// velocity > 200 deg/s 임계
let last: Sample | null = null;
return (s: Sample) => {
if (last) {
const v = Math.hypot(s.x - last.x, s.y - last.y) / (s.t - last.t) * 1000;
if (v > 200) cb();
}
last = s;
};
}
매 결정 기준
| 상황 | Approach |
|---|---|
| VR/AR primary input | gaze + pinch (Vision Pro 패턴) |
| Desktop accessibility | dwell selection (800-1500ms) |
| Analytics only | heatmap aggregation, real-time 처리 X |
| 의료 진단 | 120Hz+ 정밀 tracker, raw sample 저장 |
기본값: 정확도 1° / 60Hz / dwell 800ms — 일반 UX의 baseline.
🔗 Graph
- 부모: Human Computer Interaction
- 변형: Eye Tracking
- 응용: Accessibility (A11y)
- Adjacent: WebXR
🤖 LLM 활용
언제: VR/AR 입력 설계, gaze heatmap 분석 결과 해석. 언제 X: gaze data 정확도가 낮은 환경 (일반 webcam 기반 1° 이상 오차)에서 critical input으로 사용 — false trigger 폭주.
❌ 안티패턴
- Midas touch: 보는 것을 모두 click으로 해석 → 의도하지 않은 trigger. dwell·confirmation 필수.
- 고정 dwell time: 사용자별 적응 필요 — 노약자는 길게.
- Saccade 중 UI 깜빡임: 사용자에 멀미·혼란.
- Calibration 없이 시작: 정확도 5° 이상 → 사실상 무용.
🧪 검증 / 중복
- Verified (Apple visionOS HIG 2026; Tobii eye-tracking research; Salvucci & Goldberg I-DT 2000).
- 신뢰도 B (HCI 분야 표준이지만 architecture wiki에서는 보조 주제).
🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — saccade/fixation/vergence·WebXR·I-DT 알고리즘 |