기기가 세워진 상태로 정지하고 있을 때 가속도 센서로 각 축에 걸리는 가속도를 측정하면 x, z 축에서는 0, 그리고 y 축에는 9.8 m/s^2 값이 확인됩니다. y축의 -방향으로 9.8 m/s^2의 중력이 걸리고 있으므로 기기는 +방향으로 9.8 m/s^2 만큼 가속되는 것이기 때문입니다. 같은 이유로 기기를 책상에 눕혀놓으면 축이 바뀌면서 x, y 축에는 0, 그리고 z 축에는 +9.8 m/s^2의 가속도가 걸리게 됩니다.
그런데 다음과 같은 3D 좌표계에서 벡터 R과 Rx, Ry, Rz 사이의 각도는 수학적으로 다음과 같이 구할 수 있습니다.
수평계는 기기가 화면을 +z 방향으로 하고 누워있을 때의 x축과 y축에 대한 기울기를 구하는 것이니까 Axr과 Ayr을 구하면 됩니다.
그런데 가속도 센서는 노이즈에 민감하고, 또 기기가 사용자에 의해 움직이고 있을 때는 중력가속도에 외력이 더해지기 때문에 각도를 정확하게 측정할 수 없습니다. 그래서 여기서는 가속도 센서 대신 중력 센서를 사용할 겁니다. 중력센서는 가속도센서와 자이로스코프 보정을 통해 각 축의 중력강도만을 반환하기 때문에 외력의 영향을 무시할 수 있습니다.
@SuppressLint("SourceLockedOrientationActivity")overridefunonCreate(savedInstanceState:Bundle?){// 세로모드 고정
requestedOrientation=ActivityInfo.SCREEN_ORIENTATION_PORTRAITsuper.onCreate(savedInstanceState)setContentView(binding.root)}
중력센서의 값은 SensorEvent의 value 속성으로 가져올 수 있습니다. 공식에 따라 r 값을 계산하고 Axr과 Ayr을 계산하면 됩니다. 계산값은 라디안으로 반환되기 때문에 (180/PI)를 곱해서 각도로 변환합니다. 그리고 안드로이드 시스템의 좌표계에서 기기가 누워있는 상태는 x, y축으로 90도 회전한 상태이기 때문에 이 값을 0으로 만들기 위해 90을 빼주면 됩니다.