Dev Investigation Notes
How to recover the original snap interval from coordinate data with no recorded grid size
This is a translated article. Read the original in Korean ↗
In formation, a web app that overlays a grid on dance practice videos and lets users mark dancer positions at different times to edit formations and movement paths, the task was to align choreography data for 12 dancers across 83 keyframes to a grid. But the coordinate file had no record of the grid size originally used — it was an older format containing only an array of numbers, so the grid setting itself was gone.
Conclusion
If coordinates "roughly" fit a grid but don't line up exactly, and the grid size isn't recorded in the file, you can reverse-engineer it by trying candidate grid sizes and comparing how closely the points align with grid lines (the fit rate). When doing this, check not just a "full-cell" grid but also a half-cell grid (a grid that includes both lines and cell centers). In this case, the full-cell grid had a 55% fit rate, while the half-cell grid reached 91% — the grid with half the spacing was the actual answer .
오차·적합률 계산법: 좌표를 후보 격자 간격(step)으로 나눈 나머지를 구해, 가장 가까운 격자선까지의
거리로 바꾼다(나머지가 step/2보다 크면 step에서 뺀 값을 쓴다). 이 거리를 step 대비 비율로 정규화한
게 "오차"(0~50%)다. 오차가 허용오차(예: step의 10% 이내) 안에 드는 점의 비율이 "적합률"이다 —
허용오차를 좁게 잡을수록 맞는 후보와 틀린 후보의 적합률 격차가 커져 구분이 쉬워진다.
격자 정의: cell = gridSize × (w/800)
화면 gridSize=50 기준 정규화 간격: 가로 0.0625 / 세로 0.1111 [S:dae2585f#24][S:dae2585f#25]
1차 실측(전체 칸 격자): x 중앙값 4% · y 중앙값 7% 벗어남 → 격자 기반은 맞는데 딱 맞진 않음 [S:dae2585f#27]
2차 실측(반 칸 격자): 91% 적합 (전체 칸은 55%) → 반 칸이 실제 격자 [S:dae2585f#28]
gridSize 20~100 전체 스캔 → stepX=0.03125, stepY=0.05556 (gridSize 50의 반 칸)에서 x 90%·y 91% 최적 [S:dae2585f#29][S:dae2585f#30]
Situation
formation also has a live feature: when one leader plays a video, everyone else can connect on their phones and view the video and formation at the same point. But this case came from the step before that — cleaning up coordinates placed in the editor. Both x and y coordinates are stored normalized to 0–1 , and the grid is defined in screen pixels as cell = gridSize × (w/800) . With a video resolution of 1920×1080 (16:9), even grid cells that are square on screen have different spacing in normalized coordinates: 0.0625 horizontally and 0.1111 vertically .
Work was already underway to remove coordinate jitter and snap positions into alignment when a request kicked off the grid investigation: "Can you check the grid size too? I want to arrange the positions on the grid, but right now they're a little crooked and don't line up" .
Symptom
Calculating the grid spacing and measuring the coordinates showed that they weren't completely off (median errors of 4% for x and 7% for y) — the layout was indeed based on a grid, but snapping it directly to full cells would be wrong. Some points clustered around the middle of the cells (half-cell) . Forcing them onto full cells would destroy positions that had intentionally been placed halfway between grid lines.
Cause
- The grid size wasn't saved in the file: The saved format was a bare array containing only coordinates (the old format), rather than
{gridSize, keyframes}, so the gridSize value used during editing was gone . - The editor had no drag snapping: There was a grid slider (20–100, default 50), but no feature to snap positions to the grid while dragging, so the choreographer placed points near grid lines and cell centers by eye . That left the coordinates "almost" aligned with the grid, but not exactly.
- The "full-cell" assumption was wrong: The initial assumption was that the positions would fit the grid at the on-screen gridSize (full cells), but the actual placement used half that spacing — a half-cell grid that treated both lines and cell centers as grid points.
Fix
All we had was a suspicion that the layout was grid-based and a set of coordinate numbers with an unknown grid size. So we scanned a broad range of candidate grid sizes to reverse-engineer it statistically.
- Measure against the full-cell grid first. Calculate each coordinate's distance from the nearest grid line as an error (using the method above), then examine the median and distribution. In this case, x at 4% and y at 7% signaled that the layout was grid-based, but the fit wasn't exact .
- Look for a half-cell bias in the error distribution. If the errors cluster near the middle of a cell (half-cell) rather than near zero, halve the grid size and measure again. The half-cell grid had a 91% fit rate, far ahead of the full-cell grid's 55% .
- If the grid size itself is unknown, define a range and scan all of it. In this case, the code confirmed that the editor's slider ranged from 20 to 100, so we scanned that entire range, calculating x and y fit rates for each gridSize (and its half-cell spacing) using the method above.
stepX=0.03125, stepY=0.05556(= half a cell at gridSize 50 = a gridSize 25 grid) gave the best fit, at 90% for x and 91% for y . - Snap every point to the nearest grid point on the recovered grid, and move any two points occupying the same cell to nearby empty cells. All 1034 coordinates landed on grid points, only 7 moved more than 3% of the stage (a maximum of 3.6%), and 6 collisions were resolved by moving points to empty cells .
- A follow-up request to "try placing them more densely" led to reducing the grid from gridSize 50→25 (halving the snap interval again) and reapplying it. The maximum movement dropped from 3.6%→1.7%, with zero movements exceeding 3% . Applying the same method to another choreography file (927 coordinates) found that the same grid fit at 98% for x and 93% for y, confirming that the method's success wasn't a coincidence specific to one file .
The key was turning the feeling that "this seems to fit a grid" into a numerical fit rate, and scanning candidates that included multiples and halves of the spacing, alongside full cells. If you simply snap points while assuming you already know the grid size, you can force them into the wrong cells and destroy the intended layout, as would have happened here.
Bonus — an implementation report and actual verification are separate things
Throughout this work, each step produced reports such as "Done" and "All 1034 points landed exactly on grid points" , but this session contains no explicit sign-off from anyone who actually opened the result (the comparison viewer) and visually checked that the grid snapping was correct. The question about overwriting the original file () also went unanswered as the session moved on to another topic (mobile network configuration) . Finding a grid that fits statistically and getting visual confirmation that the result is usable are separate steps.
Reporter's Notes — why the grid was off by half a cell
The four gathered with the grid-snapping work log on screen.