flatness와 chord error
곡선 중점 B(½)가 끝점 현(chord) P0–P3에서 얼마나 떨어져 있는지가 flatness error입니다. 이 값이 tolerance 이하면 “이 구간은 직선으로 봐도 된다”고 말할 수 있습니다.
데모에서 볼 것
- 회색 cubic + 점선 chord (
P0–P3) - toolbar tolerance 0–20 px
- readout:
cubicFlatnessError = … px— chord에 대한 수직 거리(cross/chordLen)
tolerance를 낮추면 adaptive flatten(052)이 더 많이 subdivide(068)합니다.
측정 — cubicFlatnessError
import { cubicFlatnessError } from "svg-matrix-core";
const err = cubicFlatnessError(p0, p1, p2, p3);
// B(½)에서 chord P0→P3까지의 수직 거리 (px)
err = |(mid − P0) × chord| / |chord|
chordLen ≈ 0이면 끝점 거리로 fallback — degenerate segment.
quadratic:
import { quadraticFlatnessError } from "svg-matrix-core";
adaptive flatten과의 관계
engine.js의 flattenCubicAdaptive는 동일한 기하를 distancePointToSegment(B(½), P0, P3)로 검사합니다.
import { flattenCubicAdaptive, flattenPathSegmentsAdaptive } from "svg-matrix-core";
flattenCubicAdaptive(p0, p1, p2, p3, tolerance, points);
flattenPathSegmentsAdaptive(segments, { tolerance: 0.5 });
| 강의 | 멈춤 기준 | 점 개수 |
|---|---|---|
| 016 | 고정 stepsPerCurve | 예측 가능·항상 많음 |
| 069 (여기) | chord error ≤ ε | 곡률에 비례 |
| 052 | 전체 path + compareFlattenMethods | fixed vs adaptive 비교 데모 |
flatness vs 다른 “곡률” 지표
| 지표 | 비용 | 의미 |
|---|---|---|
| flatness (chord) | 매우 저렴 | “직선으로 대체해도 되나?” |
070 cubicCurvatureAt κ | 미분 2회 | offset·법선·화살표 |
| 008 bbox 극값 | 중간 | selection tight box |
급격한 코너는 flatness가 크게 나와 subdivide가 깊어집니다 — 078 offset cusp와는 다른 현상.
교차 알고리즘
075 cubicCubicIntersections — 두 cubic이 각각 flat하면 control hull chord로 교차 검사, 아니면 068 subdivide. flatness가 broad-phase 역할.
함정
- 픽셀 tolerance — zoom·viewBox에 맞게 ε 스케일 (world units vs screen px)
- flatness는 전역 최대 오차 보장이 아님 — 구간 중점만 검사; 극히 pathological handle에서는 subdivide depth로 수렴
- arc
A—arcSegmentToCubics후 cubic에 동일 adaptive (053)
Core API
cubicFlatnessError,quadraticFlatnessError—geometry.jsflattenCubicAdaptive,flattenPathSegmentsAdaptive—engine.js
관련
오늘의 핵심
flatness는 “곡률이 큰가?”의 저렴한 근사입니다. flatten·intersection·boolean에서 ε 하나로 품질–성능을 맞추고, 정밀 법선·κ는 070으로 넘기세요.