TECH 으로 돌아가기
TECH HACKER NEWS 오늘 9분 읽기 32 READS

베지어 곡선의 오래된 약점, 곡률을 직접 다뤄 고치다

베지어 곡선의 오래된 약점, 곡률을 직접 다뤄 고치다
SOURCE IMAGE · HACKER NEWS

베지어 곡선은 CAD와 컴퓨터 그래픽스의 기본기다. 1959년 폴 드 카스텔조가 고안하고 1960년대 르노에서 피에르 베지어가 다듬은 이 곡선은 수십 년이 지난 지금도 일러스트레이션과 애니메이션 도구의 기본값이거나 유일한 선택지로 남아 있다. 고정밀 CAD나 도로 설계처럼 특정 영역에서는 더 정교한 곡선이 쓰이지만, 범용 도구에서 베지어를 밀어낸 것은 아직 없다. 문제는 이 곡선에 분명한 약점이 있는데도 우리가 사실상 여기에 묶여 있다는 점이다. 그렇다면 위에 쌓아 올린 기존 기술을 무효화하지 않으면서 베지어를 더 낫게 만들 수 있을까. acko.net에 소개된 이 작업은 바로 그 질문에서 출발한다.

베지어를 그리는 과정 자체는 놀랄 만큼 단순하다. 제어점들을 선으로 잇고, 각 선 위를 동시에 같은 비율로 훑어 새 점을 만들고, 그 점들을 다시 이어 나가는 과정을 하나의 점이 남을 때까지 반복하면 그 점이 곡선 위에 놓인다. 이 선형 보간(lerp) 과정은 하나의 간결한 공식으로 정리된다. (1−t)의 내림차 거듭제곱과 t의 오름차 거듭제곱에, 파스칼 삼각형 n번째 행의 계수를 곱하는 방식이다. 곡선은 첫 제어점과 마지막 제어점만 반드시 통과하기 때문에, 고차 베지어는 형태를 다루기 어렵다. 그래서 실무에서는 제어점 4개짜리 3차 베지어만 쓰고, 큰 곡선은 여러 개의 3차 세그먼트를 접선을 맞춰 이어 붙이는 스플라인으로 만든다. 대부분의 드로잉 앱에 있는 '펜 툴'은 곡선을 직접 그리는 게 아니라 이 제어점을 그리고 편집하는 도구다.

대칭 접선이라는 착각

펜 툴에는 보통 제어점의 접선을 다루는 여러 모드가 있고, 대칭 접선이 가장 부드러운 옵션으로 제시된다. 그런데 이것은 사실 틀린 통념이며 쉽게 반증된다. 베지어는 보간 다이어그램에서 새 제어점을 읽어내는 방식으로 정확히 분할할 수 있는데, 이렇게 나눈 좌우 두 세그먼트는 원래 곡선과 100% 동일하고 이음매에서 완벽하게 붙는다. 그럼에도 중간의 접선은 거의 정중앙에서 나눈 한 경우를 빼면 비대칭이다. 곡률의 (역)반지름을 나타내는 곡률 빗(curvature comb)으로 확인해 보면, 접선이 비대칭이어도 곡률은 점프 없이 연속으로 이어진다. 즉 인접한 접선의 길이가 같은지 여부는 매끄러움과 아무 상관이 없다. 대칭 접선으로 부드러운 곡선을 그리려는 시도는 헛수고인 셈이다.

한 가지 개선책은 접선을 절댓값이 아니라 상대값으로, 예컨대 세그먼트 양 끝점 사이 거리에 비례하게 다루는 것이다. 이러면 곡선 점을 옮길 때 인접 세그먼트가 자연스럽게 휘어 비켜나 편집이 쉬워지고 첨점(cusp)도 훨씬 줄어든다. 하지만 곡률을 다시 그려 보면 이 방식도 완전하지 않다. 접선을 비례로 조정한다고 편집 중 곡률이 보존되지도, 세그먼트 사이에서 곡률이 연속으로 이어지지도 않기 때문이다. 이 대목에서 곡률 빗을 '도움 도구'라며 사용자에게 보여 주는 것이 실은 얼마나 불친절한지가 드러난다. 한쪽 끝의 곡률을 맞추면 반대쪽이 틀어져, 양쪽을 오가며 반복 조정해야 겨우 근사치에 도달한다.

곡률을 직접 다루기

더 효과적인 전략은 곡률 자체를 직접 조작하는 것이다. 일반적으로는 어려운 문제지만 여기엔 놀라운 관계가 숨어 있다. A-B-C-D 세그먼트에서 시작점의 곡률은 A, B, C의 위치에만 좌우되고 D는 무관하다. 게다가 접선 A-B가 수평이라면 C의 수직 위치만 의미가 있다. 밑바탕의 선형 보간이 여러 항을 상쇄한 결과다. 결국 시작점 곡률은 A-B의 길이와 C에서 A-B까지의 수직 거리에만 좌우되며, 반대쪽 D도 C-D, B에 대해 똑같이 성립한다. 여기서 규칙이 나온다. 곡선 점을 옮길 때는 인접 세그먼트의 시작·끝 곡률을 보존하고, 접선을 돌릴 때는 현재 세그먼트 반대편 끝과 인접 세그먼트 양쪽의 곡률을 보존하도록 접선 길이를 조정하는 것이다.

다만 접선을 돌릴 때 그 접선의 '길이'는 사용자 의도를 잘 대변하지 못한다. 작은 변화가 곡률을 크게 흔들어 곡선이 튀거나 폭발하듯 요동칠 수 있기 때문이다. 그래서 저자는 길이가 곡률에 직접 대응하는 '곡률 핸들'을 쓴다. 곡률 빗과 달리 핸들 길이는 역수가 아니라 곡률 반지름 그 자체여서 더 자연스럽고 안정적이다. 이 핸들은 필요할 때 고전적 베지어 제어점으로 즉석 변환할 수 있어 두 표현 사이를 왕복할 필요가 없고, 그 덕에 수치 오차 누적도 피할 수 있다. 실제 구현에서는 원하는 곡률과 양 끝점, 단위 접선이 주어졌을 때 접선 길이 l₀, l₁을 풀어야 하며, 이는 곡선의 1·2차 도함수와 벡터 외적으로 곡률 벡터를 구해 l₀, l₁에 대한 2차 연립방정식으로 정리된다. 두 접선이 평행하면 방정식이 분리되어 간단해지고, 상수항은 앞서 확인한 대로 수직 거리에만 영향을 받는다.

다중 해와 팝핑이라는 난제

기하적으로 이 문제는 가로·세로로 놓인 두 이중 포물선의 교점을 찾는 일이 된다. 곡률의 부호가 시계·반시계 방향을 정하므로 부호 조합 네 가지를 각각 풀어야 한다. 한 식을 l₁이나 l₀에 대해 정리한 뒤 제곱해 다른 식에 대입하면 4차 방정식이 되고, 이는 4차 공식으로 직접 풀 수 있다. 다만 제곱 과정에서 가짜 해가 섞이므로 원래 방정식을 다시 만족하는지 확인해야 하고, 접선이 180도 뒤집힌 경우인 음수 길이 해는 버린다. 대개는 유효 해가 하나뿐이라 잘 작동하며, 코너형 점처럼 곡률이 무한대인 경우도 대응하는 길이를 0으로 두면 간단히 풀린다.

진짜 어려운 부분은 유효 해가 여럿일 때다. 각 해는 서로 다른 곡선을 뜻하는데, 편집 중에 곡선이 이리저리 튀는(팝핑) 경험은 최악이다. 이전 l₀, l₁을 기억해 가장 가까운 해를 고르는 방법은 편집 순서에 따라 결과가 달라지는 경로 의존성을 낳고, 해 자체가 갑자기 생기거나 사라지므로 팝핑을 없애지도 못한다. 저자의 해법은 해들에 적절한 가중치를 설계해 가중 평균을 내는 것이다. 두 방정식의 기울기 벡터가 이루는 각(내적)으로 서로 반대 방향으로 휘어 곧 소멸할 불안정한 해를 감지해 arccos(−cosθ)로 무력화하고, 접선 길이의 크기 √(l₀²+l₁²)가 큰 해는 곡선이 자기 자신을 관통해 고리를 만드는 바람직하지 않은 경우이므로 강하게 억제한다. 이 가중치를 쓰면 시작점과 끝점을 서로 통과시키며 움직여도 곡선이 매끄럽게 변한다. 대신 여러 해를 평균 낸 (l₀, l₁)이 원래 연립방정식의 정확한 해라는 보장은 없어, 근처에 정확한 해가 있어도 결과 곡률이 항상 정확하지는 않다는 한계가 남는다.

실무적으로 이 작업이 주는 함의는 분명하다. 우리가 오랫동안 '부드러움의 척도'로 믿어 온 대칭 접선은 곡률과 무관한 착시였고, 편집 도구가 사용자 의도를 배신하는 근본 원인이었다. 곡률을 직접 다루는 핸들 방식은 기존 베지어 자료 구조를 그대로 두면서도 편집 경험을 곡선의 실제 성질에 맞춰 놓는다. 드로잉·애니메이션 툴을 만드는 개발자라면, 레거시 포맷과의 호환을 깨지 않고도 펜 툴의 체감 품질을 끌어올릴 여지가 여기에 있다는 점을 눈여겨볼 만하다.

SOURCE · HACKER NEWS
원문 전체 보기 → https://acko.net/blog/curvature-beziers/
SHARE
NEXT · CHOOSE

변화를 읽었다면,
내가 만들 수익 구조를 고릅니다.

정보를 더 모으는 데서 멈추지 않고, 광고·외주·판매·중개·구독 중 내 상황에 맞는 출발점을 정해보세요.

21가지 수익 구조 살펴보기
처리 중...