당신이 그림 앱에 "빨리 그으면 선이 가늘어지는" 붓을 넣는다고 하자. 마우스가 움직일 때마다 속도를 재서 굵기를 정한다. 그런데 똑같이 천천히 그어도 선이 어떤 데는 굵고 어떤 데는 갑자기 가늘다. 손은 고르게 움직였는데 선은 떨린다. 문제는 손이 아니라 "순간값"이다.
순간값으로 바로 움직이면 왜 떨리나
순간 측정값에 바로 반응하는 장치는 원래 움직임이 아니라 측정의 잡음을 키운다. 포인터 속도, 경로의 방향, 한 프레임의 시간 같은 값은 표본을 뜨는 간격이 들쭉날쭉하거나 원천 데이터 자체가 지그재그라서, 같은 상황에서도 몇 배씩 튄다. 이 값을 그대로 굵기·카메라·품질에 넣으면 그 튐이 화면에 그대로 나온다.
그래서 반응하기 전에 정할 것이 하나 있다. 이 값을 무엇을 기준으로 고를 것인가. 답은 상황마다 다르다.
- 시간으로 평활한다 — 값이 시간에 따라 흐르고, 조금 늦게 따라와도 되는 경우(붓 굵기, 숫자 표시)
- 거리(위치)로 평균낸다 — 값이 "어디에 있나"에 매여 있고, 같은 자리에서는 같은 답이 나와야 하는 경우(경로를 따라가는 카메라)
- 기준선 대비 비율로 본다 — 절대값이 기기·환경마다 다른 경우(프레임 시간, 응답 시간)

시간으로 평활할 때 무엇을 조심하나
브라우저의 포인터 이벤트는 고른 간격으로 오지 않는다. 한 번은 1ms 뒤에, 다음은 16ms 뒤에 온다. 순간 속도는 "움직인 거리 ÷ 걸린 시간"이라 간격이 짧은 표본 하나만으로도 속도가 몇 배로 튄다. (MDN 의 포인터 이벤트 문서도 브라우저가 이벤트를 묶어 보낸다고 적는다.)
- 속도를 굵기에 넣기 전에 지수평활(새 값을 조금씩만 섞는 이동 평균)을 거친다.
- 속도 → 굵기 곡선은 "직선으로 줄다가 바닥에서 멈춤"처럼 꺾이는 꼴보다, 어디서도 기울기가 끊기지 않는 꼴(반감 거리 지수식 등)로 둔다. 꺾이는 자리에서 작은 튐이 큰 변화가 된다.
- 새 획을 시작할 때 평활값을 0으로 되돌린다. 안 그러면 앞 획의 빠른 속도를 물려받아 새 획 머리가 가늘게 뜬다.
위치에 매인 값은 왜 시간으로 평활하면 안 되나
GPS 경로처럼 원천이 지그재그인 선을 따라가는 카메라를 생각해 보자. 카메라 방향을 "지금 서 있는 선분의 방향"(순간 접선)으로 잡으면, 점 하나를 지날 때마다 방향이 확확 바뀐다.
시간 기준 필터로 녹이면 떨림은 줄지만 두 가지가 나빠진다.
- 긴 커브에서 카메라가 비스듬히 뒤처진다 — 필터는 지난 값을 끌고 오기 때문이다.
- 답이 지나온 자취에 매인다. 같은 자리에 같은 시각에 와도, 어떻게 왔느냐에 따라 카메라가 다르다. 되감기·건너뛰기·여러 화면 동기화가 깨진다.
대신 **경로 위 앞뒤로 일정 거리 떨어진 두 점을 이은 선(현)**의 방향을 쓴다. 이 값은 "경로 위 어디인가" 하나로 정해지므로, 떨림이 줄면서도 같은 자리에서는 늘 같은 답이 나온다.
절대값 문턱은 왜 기기마다 틀리나
느린 기기에서 해상도를 자동으로 낮추는 "적응형 품질"을 넣는다면, 판단 기준을 "프레임이 20ms 넘으면 낮춘다"처럼 절대값으로 두기 쉽다. 그런데 화면은 주사율에 맞춰 그린다. 30Hz 화면은 멀쩡해도 프레임이 33ms다. 절대값 문턱은 멀쩡한 기기의 품질을 깎는다.
- 기준은 **"이 화면의 주사율 대비 얼마나 밀렸나"**로 둔다.
- 주사율은 관측한 가장 짧은 프레임 간격으로 추정하되, 예열 뒤에 잰다. 시작 직후의 짧은 프레임에 끌려가면 기준선이 틀린다.
- 성능 비교도 마찬가지다. 다른 프로그램이 함께 도는 기계에서는 같은 코드의 프레임 시간이 3~4배 흔들린다. 절대값을 견주지 말고, 같은 자리에서 바꾸기 전·후를 번갈아 재서 비율로 본다.
에이전트에게 줄 지침
측정값으로 무언가를 움직이거나 판단하기 전에:
1. 이 값이 표본 간격이나 원천 잡음 때문에 튀는지 본다(같은 동작을 반복해 분포를 찍는다).
2. 기준 축을 고른다:
- 시간에 따라 흐르고 늦어도 되는 값 → 지수평활. 새 동작이 시작되면 평활값을 초기화한다.
- 위치에 매인 값 → 위치(경로 거리) 기준 앞뒤 평균. 같은 자리 = 같은 답을 지킨다.
- 기기·환경마다 절대값이 다른 값 → 기준선(주사율, 직전 버전) 대비 비율. 기준선은 예열 뒤에 잰다.
3. 반응 곡선에 꺾이는 자리를 두지 않는다.
4. 고친 뒤 같은 지표(예: 방향 변화의 99번째 백분위)를 다시 재서 줄었는지 확인한다.
우리가 겪은 사례
- 붓 굵기: 마우스 속도로 붓 굵기를 정했더니 빨리 그을 때 너무 급격히 가늘어졌다. 포인터 이벤트 간격이 1~16ms 로 들쭉날쭉한 게 원인이었고, 지수평활·끊김 없는 곡선·획마다 초기화로 고쳤다.
- 경로 추적 카메라: 지그재그 경로를 따르는 카메라가 시점을 확확 바꿨다. 순간 접선 대신 경로 기준 앞뒤 현의 방향을 쓰자 카메라 방향 변화의 99번째 백분위가 15.2°에서 0.5°로 줄었다(같은 경로를 따라 실측).
- 적응형 품질: 약한 기기용 품질 조절을 절대 프레임 시간으로 판단하면 원래 느린 화면에서 멀쩡한데 품질을 깎는다는 것을 알고, 주사율 대비 비율로 바꾸고 주사율 추정은 예열 뒤로 미뤘다.
- 곁 사례로, 에이전트가 띄운 자동화 브라우저에서 같은 코드의 프레임 시간이 로드마다 3~4배 흔들려, 성능 판단을 바꾸기 전·후 교차 측정으로 바꿨다.