소년포비의 세계정복!!

스마트폰(PDA) 이용한 차량용 HUD 만들기 #5 - 진행 방향 본문

윈도우폰 세상/Windows Phone

스마트폰(PDA) 이용한 차량용 HUD 만들기 #5 - 진행 방향

소년포비 2009. 10. 29. 23:47

 

단순히 텍스트로 표시해 줄수도 있으나 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 로 설정되면 유리창에 대응해서 나침반 바늘의 각도가 설정된다.