10일 1월 2021

베지어 곡선

베지어 곡선(Bezier Curve)은 컴퓨터 그래픽스에서 사용되는 특별한 형태의 곡선으로, CSS 애니메이션 등에서 도형을 그릴 때 사용합니다.

곡선 자체는 매우 단순하기 때문에 한 번 공을 들여 공부해 두면 벡터 그래픽스나 고급 애니메이션을 다룰 때 도움이 됩니다.

조절점

베지어 곡선은 조절점(control point)을 사용해 정의합니다.

조절점의 개수는 2개나 3개, 4개가 될 수 있고 이보다도 많을 수 있습니다.

조절점이 두 개인 베지어 곡선을 살펴봅시다.

조절점이 세 개인 베지어 곡선은 다음과 같습니다.

네 개의 조절점이 있을 땐 다음과 같은 곡선이 나옵니다.

이 곡선들을 주의 깊게 살펴보면, 베지어 곡선은 다음과 같은 특징을 보인다는 걸 알 수 있습니다.

  1. 조절점이 항상 곡선 위에 있지는 않습니다. 이는 아주 자연스러운 현상인데, 아래쪽에서 어떻게 곡선이 만들어지는지 살펴보면 이해할 수 있습니다.

  2. 곡선의 차수는 조절점의 개수에서 1을 뺀 값입니다. 조절점이 두 개일 땐 직선, 세 개일 땐 2차 곡선, 네 개일 땐 3차 곡선이 됩니다.

  3. 곡선은 항상 조절점의 컨벡스 헐(convex hull, 볼록 껍질)안에 있습니다.

마지막 특성 덕분에 컴퓨터 그래픽스 분야에서 교차 검사(intersection test) 최적화가 가능합니다. 컨벡스 헐이 교차하지 않는다면 곡선 역시 교차하지 않기 때문입니다. 따라서 컨벡스 헐이 교차하는지 검사하면 아주 빠르게 곡선 역시 '교차하지 않는다’는 결론을 도출해 낼 수 있습니다. 위쪽 그림에서 보는 것과 같이 컨벡스 헐은 삼각형, 사각형 같은 상대적으로 단순한 형태를 띠므로 곡선의 교차 여부보다 컨벡스 헐 교차 여부를 검사하는게 훨씬 쉽습니다.

조절점을 움직이면 베지어 곡선은 직관적으로 봤을 때 아주 당연한 방식으로 다시 그려집니다.

아래 예시에서 직접 조절점을 움직여봅시다.

예시를 통해 베지어 곡선이 조절점을 이은 선(1-2, 3-4)을 향해 뻗어 나가는 것을 확인할 수 있습니다.

이런 특징을 염두하고 연습하다 보면 원하는 형태의 곡선을 만들 때 어디에 조절점을 두어야 할지 쉽게 알 수 있습니다.

예시:

카스텔조 알고리즘

베지어 곡선을 정의하는 수학 공식은 나중에 살펴보고, 그 전에 베지어 곡선을 정의하는 공식과 정확히 일치하고 곡선이 만들어지는 과정을 시각화 할 때 도움을 주는 카스텔조 알고리즘(De Casteljau’s algorithm)에 대해 알아봅시다.

먼저 조절점이 3개인 예시를 살펴봅시다.

데모와 설명을 순차적으로 써 두었습니다.

조절점 1, 2, 3을 직접 움직이고 재생 버튼을 눌러 어떻게 곡선이 만들어지는지 확인해 봅시다.

3점 베지어 곡선을 만드는 카스텔조 알고리즘은 다음과 같습니다.

  1. 조절점을 찍습니다. 데모에선 조절점 각각에 ‘1’, ‘2’, '3’이라는 이름을 붙여주었습니다.

  2. 조절점 1과2, 2와 3을 잇는 선분(갈색선)을 만듭니다.

  3. 매개변수 't’의 값을 '0’부터 시작해 '1’이 되도록 증가시킵니다. 데모에선 't’가 '0.05’씩 증가해 `0, 0.05, 0.1, 0.15, … 0.95, 1’이 되도록 하였습니다.

    t값을 사용해 다음과 같은 추가 작업을 할 수 있습니다.

    • 갈색으로 표시한 각 선분의 시작점에서 t와 비례하는 위치에 점을 찍습니다. 선분이 두 개이기 때문에 점 두 개가 만들어집니다.

      예를 들어 설명하면 다음과 같습니다. t0일 땐 두 점이 선분의 시작인 조절점 1과 2에 위치합니다. t0.25일 땐 조절점 1에서 조절점 1과 2를 이은 선분의 길이에 25%를 곱한 값만큼 떨어진 곳에 점이 위치합니다. t0.5일 땐 선분의 중간, 1일 땐 선분의 끝에 점이 위치합니다.

    • 추가작업을 통해 만든 두 점을 연결합니다. 그림에선 파란선에 해당합니다.

t=0.25 t=0.5
  1. 이제 파란색 선분에서 t 값과 비례하는 위치에 점 하나를 찍습니다. t0.25일 때(왼쪽 그림)는 파란 선분의 4분의 1지점에 빨간점을, t0.5일 때(오른쪽 그림)는 선분의 가운데에 빨간점)을 찍습니다.

  2. t0에서 1로 증가하면서 당연히 점도 계속 추가됩니다. 이때 이 점들이 바로 베지어 곡선(빨간색 포물선)을 만듭니다.

지금까진 조절점이 3개인 경우를 살펴보았는데, 조절점이 4개일 때 역시 같은 방식으로 곡선이 만들어집니다.

조절점이 네개 일때 데모를 살펴봅시다.

조절점이 4개인 경우 카스텔조 알고리즘은 다음과 같습니다.

  • 조절점 1과 2, 2와 3, 3과 4를 연결하는 선분을 만듭니다. 총 3개의 갈색 선분이 만들어집니다.
  • t0부터 시작해 1까지 증가시키면서 각 선분에 다음과 같은 작업을 합니다.
    • 선분 시작점에서 t에 비례하는 위치에 점을 찍습니다. 이 점들을 연결해 두 개의 녹색선을 만듭니다.
    • 두 개의 녹색 선분 위에 t에 비례하는 위치에 점을 찍습니다. 이 두 점을 연결 파란색 선을 그립니다.
    • 파란색 선에서 t에 비례하는 위치에 점(빨간점)을 만듭니다.
  • 이 점이 모여 곡선이 만들어집니다.

카스텔조 알고리즘은 재귀적이기 때문에 조절점 개수에 상관없이 일반화가 가능합니다.

N개의 조절점이 있을 때 알고리즘은 다음과 같습니다.

  1. N개의 조절점을 연결해 N-1개의 선분을 만듭니다.
  2. 0부터 시작해 1이 될 때까지 t를 조금씩 증가시키면서 각 선분에서 t만큼 비례한 곳에 점을 찍고, 그 선을 연결합니다. 이때 N-2개의 선분이 만들어집니다
  3. 점이 하나만 남을 때까지 2를 반복합니다.

이렇게 만들어진 점들이 모여 곡선이 됩니다.

데모를 중간중간 정지 시켜 선분과 곡선이 어떻게 만들어지는지 직접 확인해보세요.

y=1/t 형태를 띠는 곡선:

갈지자가 되게 조절점을 찍어도 곡선을 만들 수 있습니다.

예시처럼 고리 모양 베지어 곡선을 만들 수도 있습니다.

뾰족한 베지어 곡선도 물론 만들 수 있습니다.

알고리즘이 잘 이해가 안 간다면 위쪽 데모를 실행하고, 중간중간 정지 시켜 어떻게 곡선이 만들어지는지 살펴보세요.

재귀성을 띄는 알고리즘 덕분에 우리는 다양한 차수의 베지어 곡선을 얼마든지 만들 수 있습니다. 조절점이 5개, 6개 혹은 그 이상 있는 곡선을 만들 수 있죠. 그렇지만 실무에선 많은 개수의 조절점은 그다지 잘 쓰이지 않습니다. 조절점은 보통 2~3개이고, 이 조절점을 사용해 만든 곡선을 이어붙여 복잡한 그림을 그리게 됩니다. 이런 방식을 사용하면 개발과 계산 모두 간단해집니다.

조절점은 ‘통과하는’ 곡선은 어떻게 그리나요?

베지어 곡선 모양은 조절점을 사용해 정의되는데, 지금까진 곡선 양 끝을 제외하고 조절점이 곡선 위에 있는 경우는 없었습니다.

그런데 작업을 하다 보면 가끔 몇몇 점을 통과하는 곡선을 그려야 하는 경우가 생깁니다. 점 전부가 부드러운 하나의 곡선 위에 있어야 하는 것이죠. 이런 작업을 보간(interpolation)이라 부르는데 여기선 보간에 대해선 다루지 않겠습니다.

참고로 보간에는 라그랑즈 다항식(Lagrange polynomial)을 비롯한 다양한 수학 공식을 사용할 수 있습니다. 컴퓨터 그래픽스에서는 많은 점을 잇는 부드러운 곡선을 만들 때 스플라인 보간(spline interpolation)을 자주 사용합니다.

수학

베지어 곡선은 하나의 수학 공식을 사용해 설명 가능합니다.

사실 이 공식을 알 필요는 없습니다. 대다수의 사람은 공식 없이 마우스로 점을 움직여 원하는 형태의 곡선을 만듭니다. 그렇지만 수학을 좋아하는 분들을 위해 베지어 곡선을 만들 때 사용되는 식을 소개해보겠습니다.

조절점 Pi의 좌표에 대하여 첫 번째 조절점의 좌표를 P1 = (x1, y1), 두 번째 조절점의 좌표를 P2 = (x2, y2) 등이라 정의했을 때, 베지어 곡선을 이루는 점의 좌표들은 [0,1]사이의 매개변수 t값에 의해 결정됩니다.

  • 조절점이 2개일 때:

    P = (1-t)P1 + tP2

  • 조절점이 3개일 때:

    P = (1−t)2P1 + 2(1−t)tP2 + t2P3

  • 조절점이 4개일 때:

    P = (1−t)3P1 + 3(1−t)2tP2 +3(1−t)t2P3 + t3P4

위 식들은 벡터 방정식입니다. 따라서 곡선을 이루는 점의 좌표를 얻을 때 P 대신 xy를 넣으면 됩니다.

조절점이 3개인 경우를 예로 들어봅시다. 곡선은 각 점의 좌표 (x,y)를 사용해 만들어집니다.

  • x = (1−t)2x1 + 2(1−t)tx2 + t2x3
  • y = (1−t)2y1 + 2(1−t)ty2 + t2y3

x1과 y1, x2와 y2, x3과 y3엔 세 조절점의 x, y 좌표를 넣고 t0 에서 1로 증가시키면서 도출한 값들을 사용해 곡선을 만듭니다.

조절점이 (0,0), (0.5, 1), (1, 0)인 경우, 방정식은 다음과 같습니다.

  • x = (1−t)2 * 0 + 2(1−t)t * 0.5 + t2 * 1 = (1-t)t + t2 = t
  • y = (1−t)2 * 0 + 2(1−t)t * 1 + t2 * 0 = 2(1-t)t = –2t2 + 2t

0부터 시작해 1이 될 때까지 t를 증가 시켜 무수히 많은 (x,y) 조합을 만들고, 이를 연결해 곡선을 만들면 됩니다.

요약

베지어 곡선은 조절점을 사용해 정의할 수 있습니다.

여기선 두 가지 방식을 사용해 베지어 곡선을 만들어 보았습니다.

  1. 카스텔조 알고리즘을 사용해 직접 그려보기
  2. 수학 공식 사용하기

베지어 곡선은 다음과 같은 장점이 있습니다.

  • 마우스만으로 부드러운 곡선을 그릴 수 있다.
  • 베지어 곡선을 조합해 복잡한 도형을 만들 수 있다.

베지어 곡선의 사용처는 다양합니다.

  • 컴퓨터 그래픽스, 모델링, 벡터 그래픽 에디터에서 사용하고, 폰트를 만들 때 역시 베지어 곡선을 사용합니다.
  • canvas 요소나 SVG 포맷을 사용해 웹 개발을 할 때 사용합니다. 참고로 위에서 살펴본 ‘생동감 있는’ 데모는 SVG를 사용해 만들었습니다. demo.svg를 새 창에서 열고 개발자도구를 열어 직접 살펴봅시다. 데모가 조절점의 x, y 좌표가 매개변수인 하나의 SVG 문서 인 것을 확인할 수 있습니다.
  • CSS 애니메이션의 경로와 속도를 조절할 때 사용합니다.
튜토리얼 지도

댓글

댓글을 달기 전에 마우스를 올렸을 때 나타나는 글을 먼저 읽어주세요.
  • 추가 코멘트, 질문 및 답변을 자유롭게 남겨주세요. 개선해야 할 것이 있다면 댓글 대신 이슈를 만들어주세요.
  • 잘 이해되지 않는 부분은 구체적으로 언급해주세요.
  • 댓글에 한 줄짜리 코드를 삽입하고 싶다면 <code> 태그를, 여러 줄로 구성된 코드를 삽입하고 싶다면 <pre> 태그를 이용하세요. 10줄 이상의 코드는 plnkr, JSBin, codepen 등의 샌드박스를 사용하세요.