멍충이의 삽질로그
몇년쯤전 친구와 만들었던 작도 프로그램인 GCS에는 한가지 문제가 있다. y축과 평행한 직선, 즉 기울기가 무한인 직선은 사라지는 버그가 있다. 그거에 대한 이야기를 하고 싶다
GCS에서는 도형을 다음과 같이 표현했다.
class Line {
float Grad, Yint;
}
class LineSegment : Line {
Vector2 P1, P2;
}직선은 y = ax + b 꼴로 표현을 하고 선분은 두 점을 사용했다. 그리고 도형끼리의 교점이나 수선 등의 다양한 연산을 하는데 직선과 선분 모두 기울기와 y 절편를 사용했으니 x축이나 y축에 평행한 직선과 선분들은 오류가 있을 수 밖에 없었다.
그렇다면 직선을 어떻게 표현을 해야 하지? 내가 생각하는 규칙은 다음과 같았다.
- 직선 하나를 표시하는 방법이 한가지뿐이었으면 좋겠다.
- 수직이거나/수평임을 다른 방법을 통해 표현하지 않았으면 좋겠다. (일관성이 있으면 좋겠다)
- 위의 a가 무한인 경우는 부동 소수점에서 무한을 표현하는게 일반적으로 힘드므로 이것도 피했으면 좋겠다.
이에 대해 별별 해결책을 생각해보았다.
직선을 표현하는데 ax + by + c = 0 꼴의 일반형을 사용하면 2,3번은 해결이 되지만 1번이 안됨.
부동소수점을 사용하는 이상 tolerance을 사용하는건 피할 수 없는거겠지만 그래도 전체 식이 여러 꼴로 나오고 같은지 비교하기 위해 또 계산을 하는데 오차가 너무 걱정이 되더라
절편 하나와 각만 알면 직선을 표현할 수 있잖아? 라고 생각했다. 기본적으로 grad-yint 데이터와 다를게 거의 없지만 무한이라는 기울기를 90도로 표현할 수 있는게 좋았다. 물론 생각해보니 미친 생각같아서 넘겼다. 도형끼리의 간단한 연산 하나하나를 할때마다 삼각함수를 부를 생각을 하니 아찔하더라
물론 이거 하나때문에 포기한게 아니다. 각이 0도이면 x절편이, 90도면 y절편이 구해지지 않아서 짜증나서 버렸다.
1번을 완벽하게 비껴나가는 해결책이었다. 동시에 초창기에 사용하던 방법이기도 했다
다른 큰 프로젝트는 어떻게 햇을까?
cgal의 Line_2 는 ax + by + c = 0 을 쓰더라.
dgtal의 DSL 에서는 두 점을 쓰더라
cgal은 코드를 더 뒤져보다가 진짜 세상 놀라워서 못보겠고 dgtal은 귀찮아서 더 안봤음 외에 작도 시뮬레이션 코드도 보다가 대부분 두 점 쓰는거랑 그거때문에 귀찮은 처리가 많아지는거 보고 그냥 안봤음
사실 종이접기 시뮬레이션 만드려다 이 직선 표현하는거 때문에 뇌에 힘 많이 주다 귀찮아서 좀 지껄여봤다 결과는 딱히 모르겠음 잘 나가는 라이브러리가 저런거 쓰는거 보면 둘 따라해서 적당히 만들어도 별 문제 없지 않을까?
개같은 부동소수점때문에 골머리 많이 썩힌다
GCS를 만드는데 가장 머리아팠던건 도형과 도형의 교점을 찾는거였다. N종류의 도형이 있었을때 NxN 전부를 하나하나 디스패치해서 처리하는게 참 개같았는데 cgal 코드를 보니 나만 그랬던게 아닌거 같더라
타원과 타원의 교점같은거 구하거나 선분과 오브젝트에서 선분의 모서리에 닿는지 등을 처리하는데 진짜 골때렸는데 부동소수점으로 수학을 표현하는거는 어느정도 한계가 있고 그걸 극복하는덴 많은 노력이 쓰이는거 같더라 나같은 초보가 가벼운 마음으로 핥아볼만한 주제가 아님을 꺄달앗음
마운틴듀 마시고 싶다