티스토리 뷰

프로그램/안드로이드 강좌

나침반 예제

서.라.연 2012. 8. 15. 13:55


이 자료들은 팁스소프트에서 제공하는 [ 알짜배기 ] 프로그램을 이용하면 더 편리하게 볼수 있습니다.
* 알짜배기 프로그램 받기 - http://www.tipssoft.com/bulletin/tb.php/QnA/8406
* 관리자의 Tipssoft 이야기를 들어보세요 ( 트위터 ID : tipssoft )
* 안드로이드 강좌 목록 - http://www.tipssoft.com/bulletin/tb.php/old_bbs/501
* 이 예제는 안드로이드 팜으로 만들어졌습니다.

이 예제는 안드로이드용 기기에서 제공하는 가속도 센서와 자기장 센서를 이용하여 기기의 방위를
계산하고 방위에 맞게 나침반을 그리는 예제입니다. 데이터 산출은 메인 액티비티에서 수행하고
나침반은 별도의 사용자 정의 뷰에 그리도록 하였으며, 나침반은 별도의 이미지를 사용하지 않고,
Canvas 클래스에서 제공하는 멤버 메소드를 사용하여 직접 그려서 구현하였습니다. 어플리케이션을
사용하는 중에 화면이 꺼지는 것을 방지하기 위하여 꺼짐 방지 기능도 추가하였습니다.
이 예제는 아래에 링크된 자료를 기초로 구성되었습니다.
센서 - 방향센서 사용하기 : http://www.tipssoft.com/bulletin/tb.php/FAQ/1036
1. 실행 화면
2. 주요 소스 코드
ExamCompassActivity 부분...
// 측정한 값을 전달해주는 메소드.
public void onSensorChanged(SensorEvent event)
{
if(event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
// 가속 센서가 전달한 데이터인 경우
// 수치 데이터를 복사한다.
m_acc_data = event.values.clone();
} else if(event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
// 자기장 센서가 전달한 데이터인 경우
// 수치 데이터를 복사한다.
m_mag_data = event.values.clone();
}

// 데이터가 존재하는 경우
if(m_acc_data != null && m_mag_data != null) {
// 가속 데이터와 자기장 데이터로 회전 매트릭스를 얻는다.
SensorManager.getRotationMatrix(m_rotation, null, m_acc_data, m_mag_data);
// 회전 매트릭스로 방향 데이터를 얻는다.
SensorManager.getOrientation(m_rotation, m_result_data);

// Radian 값을 뷰에 전달한다.
m_compass_view.setAzimuth(m_result_data[0]);

String str;
// Radian 값을 Degree 값으로 변환한다.
m_result_data[0] = (float)Math.toDegrees(m_result_data[0]);

// 0 이하의 값인 경우 360을 더한다.
if(m_result_data[0] < 0) m_result_data[0] += 360;

// 첫번째 데이터인 방위값으로 문자열을 구성하여 텍스트뷰에 출력한다.
str = "방위 : " + (int)m_result_data[0];
m_check_view.setText(str);
}
}
CompassView 부분...
// 사용자정의 뷰의 출력 형식을 정의하는 오버라이딩된 메소드
protected void onDraw(Canvas canvas)
{
// 원을 그린다.
canvas.drawCircle(m_center_x, m_center_y, m_radius, m_circle_paint);

// 방향 데이터가 존재하는 경우
if(NULL_RADIAN != m_azimuth_data) {
// 삼각형 중 데이터의 위치가 되는 뿔부분 말고 나머지 밑의 각을 구한다.
float left_radian = (float)(m_azimuth_data + Math.PI/2) % (float)(2*Math.PI);
float right_radian = (float)(m_azimuth_data + Math.PI*3/2) % (float)(2*Math.PI);

Path s_path = new Path();
// 데이터의 위치를 좌표로 변환한다.
float x = m_center_x + (float)(Math.sin(m_azimuth_data)*m_radius);
float y = m_center_y + (float)(Math.cos(m_azimuth_data)*m_radius);
// path 의 시작점을 설정한다.
s_path.moveTo(x, y);

// 나머지 삼각형의 각을 좌표로 변환한다.
x = m_center_x + (float)(Math.sin(left_radian)*50);
y = m_center_y + (float)(Math.cos(left_radian)*50);
// path 의 이동점을 설정한다.
s_path.lineTo(x, y);

// 나머지 삼각형의 각을 좌표로 변환한다.
x = m_center_x + (float)(Math.sin(right_radian)*50);
y = m_center_y + (float)(Math.cos(right_radian)*50);
// path 의 이동점을 설정한다.
s_path.lineTo(x, y);
// path를 닫는다.
s_path.close();

// path로 구성한 삼각형을 파랑색으로 칠한다.
canvas.drawPath(s_path, m_blue_paint);

Path n_path = new Path();
// 데이터의 위치를 반대 방향으로 뒤집는다.
float reverse_radian = (float)(m_azimuth_data + Math.PI) % (float)(2*Math.PI);
// 데이터의 위치를 좌표로 변환한다.
x = m_center_x + (float)(Math.sin(reverse_radian)*m_radius);
y = m_center_y + (float)(Math.cos(reverse_radian)*m_radius);
// path 의 시작점을 설정한다.
n_path.moveTo(x, y);

// 나머지 삼각형의 각을 좌표로 변환한다.
x = m_center_x + (float)(Math.sin(left_radian)*50);
y = m_center_y + (float)(Math.cos(left_radian)*50);
// path 의 이동점을 설정한다.
n_path.lineTo(x, y);

// 나머지 삼각형의 각을 좌표로 변환한다.
x = m_center_x + (float)(Math.sin(right_radian)*50);
y = m_center_y + (float)(Math.cos(right_radian)*50);
// path 의 이동점을 설정한다.
n_path.lineTo(x, y);
// path를 닫는다.
n_path.close();

// path로 구성한 삼각형을 빨강색으로 칠한다.
canvas.drawPath(n_path, m_red_paint);
}
}

public void setAzimuth(float parm_data)
{
// Radian 값을 멤버 변수에 저장한다.
m_azimuth_data = parm_data;
// 화면을 갱신한다.
invalidate();
}

 

댓글