Skip to content

[feat/MAT-362] Catmull-Rom + frozen prefix 증분 path 빌드#304

Open
b0nsu wants to merge 1 commit intorefactor/mat-361-native-stylusfrom
refactor/mat-362-catmull-rom
Open

[feat/MAT-362] Catmull-Rom + frozen prefix 증분 path 빌드#304
b0nsu wants to merge 1 commit intorefactor/mat-361-native-stylusfrom
refactor/mat-362-catmull-rom

Conversation

@b0nsu
Copy link
Copy Markdown
Collaborator

@b0nsu b0nsu commented Apr 30, 2026

Summary

quadratic Bezier를 centripetal Catmull-Rom으로 교체하고, IncrementalPathBuilder로 frozen prefix 증분 빌드를 도입합니다.
시나리오: 200 points 획 → 전체 재계산 O(n) → 마지막 segment만 O(1).

Stacked PR 7/10 — base: refactor/mat-361-native-stylus

Linear

Changes

  • smoothing.ts — centripetal Catmull-Rom 알고리즘, IncrementalPathBuilder, centripetalControlPointsMut
  • DrawingCanvas에서 buildSmoothPath → IncrementalPathBuilder 연동
  • index.ts export 추가

Testing

  • pnpm typecheck 통과
  • pnpm lint 통과

Risk / Impact

  • 영향 범위: 필기 path smoothing 알고리즘 전면 교체
  • 확인이 필요한 부분: 시각 품질, 증분 빌드 정확성
  • 배포 시 유의사항: 없음

@linear
Copy link
Copy Markdown

linear Bot commented Apr 30, 2026

@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 30, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
pointer-admin Ready Ready Preview, Comment May 8, 2026 3:34pm

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

네이티브 드로잉의 path smoothing을 기존 quadratic Bézier 기반에서 centripetal Catmull‑Rom(→ cubic Bézier) 기반으로 교체하고, 라이브 드로잉 중에는 frozen prefix를 재사용하는 증분 path 빌더를 도입해 매 포인트 입력 시 전체 재빌드 비용을 줄이려는 PR입니다.

Changes:

  • buildSmoothPath를 centripetal Catmull‑Rom 기반 cubic Bézier path 생성으로 변경
  • IncrementalPathBuilder를 추가해 라이브 스트로크에서 frozen prefix 증분 빌드 적용
  • 패키지 public export에 IncrementalPathBuilder, centripetalControlPointsMut 노출 및 DrawingCanvas에서 증분 빌더 사용

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
packages/pointer-native-drawing/src/smoothing.ts centripetal Catmull‑Rom 제어점 계산 + full rebuild + frozen prefix 증분 빌더 추가
packages/pointer-native-drawing/src/DrawingCanvas.tsx 라이브 드로잉 시 IncrementalPathBuilder.update()로 path 갱신 및 cancel/start 시 reset 연동
packages/pointer-native-drawing/src/index.ts smoothing 관련 신규 export 추가

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +10 to +23
// ---------------------------------------------------------------------------
// Catmull-Rom control points (centripetal parameterization)
// Mutable singleton to avoid per-call allocation. Safe in single-threaded JS.
// ---------------------------------------------------------------------------

const _cpOut = { cp1x: 0, cp1y: 0, cp2x: 0, cp2y: 0 };

export function centripetalControlPointsMut(
p0: Point,
p1: Point,
p2: Point,
p3: Point
): typeof _cpOut {
const d01 = Math.sqrt(Math.sqrt((p1.x - p0.x) * (p1.x - p0.x) + (p1.y - p0.y) * (p1.y - p0.y)));
Comment on lines +148 to +149
// points[i+2]가 아직 없는 마지막 ~2 segments는 확정 불가.
const canFreezeUpTo = Math.max(0, points.length - 3);
Comment on lines 89 to 93

const livePath = useRef<SkPath>(Skia.Path.Make());
const pathBuilder = useRef(new IncrementalPathBuilder());
const currentPoints = useRef<Point[]>([]);
const strokesRef = useRef<Stroke[]>([]);
DocumentSnapshot,
} from './model/drawingTypes';
export { buildSmoothPath } from './smoothing';
export { buildSmoothPath, IncrementalPathBuilder, centripetalControlPointsMut } from './smoothing';
@b0nsu b0nsu force-pushed the refactor/mat-361-native-stylus branch from 4e9555a to 255d565 Compare May 8, 2026 15:27
…path 빌드

- smoothing.ts: quadratic bezier → Catmull-Rom (centripetal parameterization, cubic Bézier)
  - centripetalControlPointsMut: mutable singleton internal-only (외부 export 안 함)
  - canFreezeUpTo = N-2 (segment i=N-3까지 freeze 가능, off-by-one 정정)
- IncrementalPathBuilder: frozen prefix 증분 빌더 — 마지막 1 segment만 live 재계산 O(1)
- DrawingCanvas.tsx:
  - pathBuilder lazy init (useRef + nullish-coalescing assign)
  - addPoint/startStroke: pathBuilder.update 호출 (full rebuild 회피)
  - finalizeStroke/cancelStroke/clear: pathBuilder.reset()

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants