단순히 텍스트로 표시해 줄수도 있으나 HUD 로 사용하려면 실제 나침반처럼 보여야 더 직관적일 것이다.
나침반은 모두 GDI 를 이용해 그리는데, 한가지 주의할점은 나침반 역시 전면 유리에 반사되어 보여야 하므로, 실제 진행 방향값을 적절히 변경해 주는 작업이 필요하다. 그건 아래에서 다시 보자.
나침반은 나침반 테두리를 원형으로 그리고, 그 위에 바늘을 출력하는 간단한 형태이다. 실제 계속 변경되어야 하는것은 바늘이므로 바늘 좌표만 회전 시키면 된다.
A 에서 B 로 회전시킬때 그림에서는 중심점을 0으로 잡고 있으나, 실제 좌표 계산에서는 화면 좌측 시작이 0 이므로, 나침반 가운데를 (0,0)으로 맞추는 변환을 수행하여야 한다.
바늘로 쓰일 4개의 좌표에 대한 회전은 삼각함수를 이용하면 쉽게 계산할 수 있다.
* 좌표 회전
실제 코드는 아래와 같다.
public static Point Rotate(Point p, Point axis, double angle) {
int x = p.X - axis.X;
int y = p.Y - axis.Y;angle = Math.PI * angle / 180.0;
int rx = (int)(x * Math.Cos(angle) - y * Math.Sin(angle));
int ry = (int)(x * Math.Sin(angle) + y * Math.Cos(angle));return new Point(rx + axis.X, ry + axis.Y);
}
앞서 말한 바와 같이 유리창에 비춰졌을 때 정상적으로 보여져야 하므로 위 코드를 아래와 같이 수정하였다.
public static Point Rotate(Point p, Point axis, double angle , bool mirror_mode) {
if (mirror_mode) {
angle = 180 - angle;
}int x = p.X - axis.X;
int y = p.Y - axis.Y;angle = Math.PI * angle / 180.0;
int rx = (int)(x * Math.Cos(angle) - y * Math.Sin(angle));
int ry = (int)(x * Math.Sin(angle) + y * Math.Cos(angle));return new Point(rx + axis.X, ry + axis.Y);
}
가장 마지막 mirror_mode flag 가 true 로 설정되면 유리창에 대응해서 나침반 바늘의 각도가 설정된다.