fix(study): 필압 굵기 차이 대폭 키움 — thinning 0.55, MIN_PRESSURE 0.25

해석 오류 정정: 사용자 "필압 너무 차이나" = "차이가 너무 *안* 난다" 의미였음. 종이
만년필 reference (4 stroke 굵기 차이 5:1) 가 *원하는* 수준이었던 걸 반대로 해석해서
thinning 줄였던 회귀.

Fix:
- thinning 0.18 → 0.55. 폭 변동 ±55%.
- MIN_PRESSURE 0.4 → 0.25. dynamic range 넓게 (0.25~1.0).
- PRESSURE_WINDOW 12 → 8. 압력 변화 빠르게 따라옴.

조합 시 실제 굵기 비율: 약한 stroke ≈ size×0.42, 강한 stroke ≈ size×1.0 → 약 2.4:1.
종이 reference (5:1) 보다는 약하지만 만년필 felt 명확.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Hyungi Ahn
2026-04-27 15:28:39 +09:00
parent 9af928b7d7
commit 1a93c9cbe6
@@ -214,10 +214,10 @@
if (!path) {
const outline = getStroke(pts, {
size,
// thinning 0.18 — 압력 차이에 stroke 폭 ±18% 반응. 사용자 보고 "필압 너무
// 차이나" = 작은 압력 변동이 큰 굵기 차이로 변환되어 일관성 없음. 0.28 →
// 0.18 로 줄여 stroke 간 일관성 강화. PRESSURE_WINDOW 12 평균으로 보정.
thinning: 0.18,
// thinning 0.55 — 압력 변동에 stroke 폭 큰 변동. 종이 만년필 reference 의
// 5:1 굵기 차이를 부분적으로 재현 (MIN_PRESSURE 0.25 floor 와 조합 시 실제
// 비율 약 2.4:1). Notability felt 의 핵심 = 압력에 따른 큰 굵기 차이.
thinning: 0.55,
smoothing: 0.99,
streamline: 0.75,
simulatePressure: false,
@@ -330,11 +330,10 @@
return e.pointerType === 'pen' || e.pointerType === 'mouse';
}
// 약한 pressure 에서도 stroke 가 너무 가늘어져 *점선* 처럼 보이지 않도록 floor.
// 사용자 보고: 쓰다보면 pressure 가 줄어 "학" 의 ㅡ 같은 부분이 거의 안 보임.
// 0.4 floor + thinning 0.28 = pressure 변동 폭 ±17% 정도, 만년필 변화 명확하면서
// 너무 가늘어지지 않음.
const MIN_PRESSURE = 0.4;
// pressure dynamic range — 만년필 reference (종이) 의 큰 굵기 차이 (약 5:1)
// 재현 위해 floor 0.25. thinning 0.55 와 조합 → 약한 stroke ≈ size×0.42, 강한
// stroke ≈ size×1.0. 비율 약 2.4:1 (적당한 만년필 felt).
const MIN_PRESSURE = 0.25;
function normalizePressure(p: number | undefined): number {
if (typeof p !== 'number' || !Number.isFinite(p)) return 0.5;
return Math.max(MIN_PRESSURE, Math.min(1, p));
@@ -350,7 +349,7 @@
// 살짝 변동시켜 thinning 적용 시 *점 간 micro 폭 변동 = 마디* 일으키던 회귀를
// 차단. window 평균은 큰 흐름만 반영, 매 점 변동은 1/N 수준. 사용자 보고 "선
// 사이사이 애매한 끊어짐" 의 원인이었음.
const PRESSURE_WINDOW = 12;
const PRESSURE_WINDOW = 8;
function smoothPressureWindow(pts: Point[], current: number): number {
let sum = current;
let count = 1;