PerfectVector
작성: Irene Kim

배율을 혼동하지 않고 SVG 경로 길이 측정하기

브라우저 사용자 단위로 SVG 경로를 측정하고 변환과 명목 크기를 반영하세요. 윤곽 길이 합계를 pathLength 보정이나 기계 이동 거리와 구분합니다.

7분 읽기
목차

SVG 경로를 측정하려면 도형 요소에서 getTotalLength()를 호출한 다음 그 수치의 좌표계를 확인하세요. 브라우저는 사용자 단위의 길이를 반환합니다. 그 수치가 자동으로 표시 길이, 밀리미터 측정값, 기계 이동 거리가 되는 것은 아닙니다.

예를 들어 직접 만든 이 대각선의 길이는 50사용자 단위입니다. 균일한 확대를 적용하면 루트 좌표계 길이는 100으로 두 배가 되고, 가로 방향만 확대하면 약 72.111이 됩니다. 두 경우 모두 로컬 API 결과는 50으로 유지됩니다. 이 수치들은 서로 다른 측정 질문에 답합니다.

그림을 측정하기 전에 알려진 선분 측정하기

도형에 접근할 수 있는 SVG와 인라인 SVG 및 JavaScript를 실행하는 브라우저가 필요합니다. 그림의 사본으로 작업하세요. 결과를 기록하기 전에 로컬 도형, 변환된 도형, 지정한 실물 크기의 길이 중 무엇이 필요한지 정합니다.

경로는 이동, 직선, 곡선, 닫기 등의 명령으로 이동 경로를 저장합니다. 사용자 단위는 해당 SVG 좌표계에 속합니다. 매핑을 확인하지 않고 픽셀이나 밀리미터라고 바꿔 부르지 마세요. MDN의 getTotalLength() 참고 문서는 결과를 브라우저가 계산한 사용자 단위 경로 길이로 정의합니다.

다음 완전한 HTML 예제는 직선 하나를 측정합니다. HTML 파일로 저장하고 브라우저에서 여세요.

<!doctype html>
<html lang="en">
<meta charset="utf-8">
<title>SVG length control</title>
<svg width="240" height="240" viewBox="0 0 120 120">
  <path id="route" d="M10 10 L40 50"
        fill="none" stroke="black" />
</svg>
<pre id="result"></pre>
<script>
  const route = document.querySelector("#route");
  document.querySelector("#result").textContent =
    route.getTotalLength() + " local user units";
</script>
</html>

가로 변화는 30, 세로 변화는 40이므로 예상 길이는 sqrt(30² + 40²) = 50입니다. 복잡한 곡선이나 가져온 엠블럼의 수치를 믿기 전에 화면 결과로 알려진 대조군을 확보할 수 있습니다. 240픽셀 뷰포트가 이 로컬 결과를 100사용자 단위로 바꾸지는 않습니다.

이 브라우저 시험에서는 허용 오차를 0.01사용자 단위로 정했습니다. 반지름 10인 4분의 1원 대조군의 해석적 길이는 5π, 약 15.708입니다. 시험 브라우저는 Chrome 155로 보고됐고 약 15.7102를 반환해 허용 오차 안에 들었습니다. 브라우저는 곡선 길이를 수치적으로 계산합니다. 모든 구현에서 소수점 끝자리까지 같기를 요구하지 말고 유용한 정밀도를 유지해 적절한 허용 오차와 비교하세요.

로컬 길이와 변환된 길이 구분하기

다음 시험 파일 두 개는 같은 d="M10 10 L40 50"을 유지하면서 변환을 추가합니다.

원본 선분로컬 API 길이명시한 변환 후 루트 SVG 사용자 단위 길이
변환 없음5050
scale(2)50100
scale(2 1)50약 72.111

균일 확대는 모든 방향에 같은 크기를 곱하므로 두 번째 행에서는 로컬 길이에 2를 곱하면 됩니다. 비균일 확대는 방향에 따라 다르게 작용합니다. 세 번째 행의 바뀐 선분은 가로 60단위, 세로 40단위이므로 50 × 2가 아니라 sqrt(60² + 40²)입니다.

SVG 좌표계 규격은 변환과 viewBox 매핑이 좌표계를 만드는 방식을 설명합니다. 목표 공간을 명시하세요. 루트 SVG 사용자 단위의 길이도 뷰포트의 CSS 픽셀과는 다릅니다.

이 알려진 직선의 끝점을 루트 SVG 사용자 좌표계에 매핑했습니다.

const root = route.ownerSVGElement;
const relative = root.getCTM().inverse().multiply(route.getCTM());
const a = new DOMPoint(10, 10).matrixTransform(relative);
const b = new DOMPoint(40, 50).matrixTransform(relative);
const transformedLength = Math.hypot(b.x - a.x, b.y - a.y);

루트 역행렬은 루트의 뷰포트 매핑을 제거하고, 상대 행렬은 경로를 루트 사용자 좌표계로 옮기는 변환을 유지합니다. 이 코드는 문서에 연결된 SVG, 역행렬을 구할 수 있는 행렬, 위의 특정 직선을 전제로 합니다. 끝점은 해당 경로 원본에서 알고 있는 값입니다.

곡선에서 두 끝점 사이는 현의 길이일 뿐입니다. 일반적으로 변환된 곡선을 측정하려면 도형을 목표 좌표계로 변환한 뒤 그 도형을 측정하거나, 분리된 윤곽을 보존하는 통제된 수치 근사를 사용하세요. 곡선 경로에 이 끝점 공식을 적용하거나 비균일 변환된 도형에 추측한 배율 하나를 곱하지 마세요.

균일·비균일 확대, 윤곽 두 개의 엠블럼, 로컬 경로 길이, 명목 밀리미터 계산을 보여 주는 실제 브라우저 측정 대조군
직접 작성한 원본 도형과 실시간 브라우저 결과입니다. 로컬 길이, 루트 좌표계에서 변환된 길이, 계산한 명목 밀리미터를 따로 표시했습니다. 대상 애플리케이션이나 실제 제작 시험은 아닙니다.

매핑을 정한 뒤 밀리미터로 변환하기

원본 엠블럼 문서는 width="50mm", height="50mm", viewBox="0 0 100 100"을 선언합니다. 의도한 균일 매핑에서는 사용자 단위당 0.5 mm입니다. 엠블럼의 바깥 너비는 80단위이므로 명목 너비는 40 mm입니다.

두 윤곽 길이의 합은 380사용자 단위입니다. 선언한 배율에서는 다음과 같습니다.

50 mm / 100 user units = 0.5 mm per user unit
380 user units × 0.5 mm per user unit = 190 mm of contours

이는 작성한 치수로부터 계산한 값입니다. 인쇄물을 측정하거나 모니터를 자로 확인하거나 편집기의 가져오기 크기를 시험하지 않았습니다. CSS가 SVG 뷰포트를 덮어쓸 수 있고 대상 도구에서 그림 배율을 바꿀 수 있습니다. 명목 계산을 제작 측정값으로 취급하기 전에 대상 도구에서 전달 치수를 확인하세요.

문서 전체 너비와 그 안의 그림 너비도 다릅니다. 대신 엠블럼의 바깥 너비만 50 mm로 정하면 80단위 너비에서 다른 계수인 50 / 80 = 0.625 mm per unit가 나옵니다. 같은 380단위가 237.5 mm의 윤곽을 나타내게 됩니다. 어느 너비를 정했는지 기록하세요. 먼저 범위를 확인해야 한다면 SVG 경계 상자 가이드를 사용합니다.

pathLength는 도형 크기를 바꾸지 않고 거리를 보정합니다

원래 50단위 선분에 pathLength="1"을 넣은 사본도 만들었습니다. getTotalLength() 결과는 50으로 유지됐습니다. 이 속성은 끝점을 바꾸거나 도형 길이를 한 단위로 만들지 않았습니다.

SVG 도형 API 규격은 계산 결과에서 pathLength를 명시적으로 제외합니다. MDN의 pathLength 참고 문서는 스트로크 대시를 포함한 경로상 거리 동작을 보정하는 기능을 설명합니다. 정규화된 거리로 효과를 만들 때 유용하지만 바탕 경로를 측정하는 작업을 대신하지는 않습니다.

그림이 점차 나타나는 효과는 SVG 스트로크 애니메이션 가이드를 따르세요. 보정한 대시 값과 그림 점검용으로 기록하는 도형 길이를 구분합니다.

윤곽을 더하되 기계 이동 거리로 취급하지 않기

이 엠블럼에는 바깥 경계와 마름모 구멍이 있습니다. 원본 복합 경로는 닫힌 두 윤곽을 모두 저장합니다.

<path fill-rule="evenodd"
      d="M10 10 H90 V60 L50 90 L10 60 Z
         M50 25 L65 45 L50 65 L35 45 Z" />

바깥 윤곽은 280단위, 안쪽은 100단위입니다. 복합 경로는 380을 반환했고, 두 윤곽을 별도 경로 요소로 측정해 더해도 380이 나왔습니다. SVG 경로 규격은 새 하위 경로와 선·닫기 선분을 구분합니다. 구멍으로 이동한다고 윤곽 사이를 잇는 그려진 선분이 추가되지는 않습니다.

이 합계는 선택해 저장한 도형을 설명합니다. 굵은 선을 트레이싱하면 경계 경로가 두 개일 수 있고, 중복 경로는 도형을 다시 더할 수 있으며, 엠블럼에는 처리할 의도가 없던 작은 내부 윤곽이 있을 수 있습니다. 실제로 뜻하는 객체와 윤곽을 측정하고 합계를 해석하기 전에 점검하세요.

기계 이동 거리는 별도 결과입니다. 작업에는 윤곽 사이 이동, 순서 선택, 반복 통과, 대상 도구별 경로 변경이 포함될 수 있습니다. 이 브라우저 합계는 어느 것도 입증하지 않습니다. 절단 시간, 재료 소비량, 성공적인 기계 결과도 알려 주지 않습니다. 스캔 그림에서 중심 경로 하나가 필요하다면 단일 선 SVG 가이드가 그 다른 재구성 작업을 다룹니다.

전제와 함께 측정값 기록하기

  1. 선택한 도형을 식별하고 여러 윤곽이나 중복이 있는지 확인합니다.
  2. 알려진 대조군과 선택한 경로를 로컬 사용자 단위로 측정합니다.
  3. 결과에 필요한 변환과 좌표 공간을 기록합니다.
  4. 단위를 바꾸기 전에 의도한 문서 또는 그림 치수를 정합니다.
  5. 보정값, 윤곽 합계, 대상 도구 측정값에 별도 레이블을 유지합니다.

알려진 직선 대조군이 명시한 허용 오차 안에서 50을 반환하지 않으면 어떤 요소를 선택했고 원본 데이터가 바뀌었는지 확인하세요. 로컬 결과는 맞지만 명목 크기가 다르다면 경로를 고치기 전에 뷰포트, 변환, 대상 도구 배율을 살펴봅니다. 소수점 자릿수를 늘려도 잘못된 좌표 매핑은 해결되지 않습니다.

다른 사람이 선택한 윤곽 합계를 재현하고 단위, 매핑, 허용 오차, 포함 객체를 이해할 수 있으면 파일 도형 점검이 끝납니다. 보관한 브라우저 시험 파일은 이 수치 대조군을 통과했습니다. 편집기 가져오기, 기계 이동, 실물 크기 시험은 하지 않았습니다.

원본이 비트맵뿐이라면 PerfectVector 이미지-벡터 과정으로 먼저 편집 가능한 SVG 도형을 재구성할 수 있습니다. 복원한 윤곽과 구멍을 확인한 다음 명시적인 배율로 선택한 도형을 측정하세요. 벡터화는 픽셀에서 경로를 만듭니다. 잃어버린 실물 크기를 복원하거나 중심선을 추론하거나 기계 이동 거리 추정값을 제공하지는 않습니다. 기존 벡터 원본이 있다면 보존하세요. 이 글의 엠블럼은 직접 작성했으며 트레이싱하지 않았습니다.

자주 묻는 질문

getTotalLength()는 픽셀이나 밀리미터를 반환하나요? 브라우저가 계산한 SVG 사용자 단위 길이를 반환합니다. 결과를 뷰포트 픽셀이나 명목 물리 단위로 표현하기 전에 좌표와 크기 매핑을 정하세요.

경로를 확대해도 로컬 API 결과가 그대로인 이유는 무엇인가요? 저장된 로컬 경로와 변환된 표현은 서로 다른 좌표 공간에 있습니다. 같은 데이터의 이 선분은 균일·비균일 확대 후 모두 로컬에서 50을 반환했습니다. 변환된 길이는 루트 SVG 단위로 100과 약 72.111이었습니다.

pathLength="1"은 경로 길이가 한 단위라는 뜻인가요? 지원되는 경로상 거리 동작에 보정값을 제공합니다. 도형 API가 계산한 길이는 그 속성을 무시합니다. 이 50단위 대조군은 여전히 50을 반환했습니다.

윤곽 합계로 절단 시간을 추정할 수 있나요? 합계만으로는 부족합니다. 대상 도구가 생성한 경로, 윤곽 사이 이동, 반복 통과, 속도 변화, 재료 특성을 확인하지 않기 때문입니다. 실제 대상 도구의 작업 점검과 적절한 제작 시험을 사용하세요.

출처

  1. MDN: SVGGeometryElement.getTotalLength() — 브라우저가 계산한 사용자 단위 경로 길이입니다.
  2. W3C SVG 도형 API — 계산한 길이와 pathLength 보정으로부터의 독립성입니다.
  3. W3C SVG 좌표계 — 뷰포트, viewBox, 변환 매핑입니다.
  4. MDN: pathLength — 경로상 거리 동작의 보정입니다.
  5. W3C SVG 경로 — 하위 경로, 그려진 선분, 닫기 명령입니다.

측정 전에 비트맵에서 편집 가능한 도형이 필요하나요? SVG 후보를 만들고 어떤 윤곽이 포함됐는지 확인한 뒤, 길이를 기록하기 전에 의도한 배율을 정하세요.

블로그의 다른 글

PerfectVector

편집하기 쉬운
더 깔끔한 SVG로 다시 시작하세요

신용카드 불필요