Page 3 of 4
When onSensorChanged() fires we have values for the Azimuth, Pitch and Roll. We're trying to get the tilt, which is the direction, and the angle, or the steepness, from these. When you think about it, the Azimuth value isn't needed for this as you can in fact treat the pitch and roll values as the x and y co-ordinates of the point in a rectangular co-ordinate system.
In the above diagram point P can be expressed as (x, y) when using rectangular co-ordinates, or (R, t) using polar ones. This is where the java Math package comes to the rescue. A quick read of the api shows us there are exactly the functions we need for this, using the orientation values we just read. From the calcAngle() method:
Some more adjustments must be made to the angle according to the quadrant the point is positioned in, but after that we're done. At any time in our app, the mAngle value will show which way the handset is tilted, and the mTilt value how steep the tilt is.
In this application we will make use of these just by showing a radar type display with an arrow at the centre. The arrow will point in the tilts direction, and its length will show the steepness. So if the handset is perfectly flat there should be no arrow.
The applications onDraw() method draws the background, then the circle, centre and markers and calls drawArrow() to show the arrow:
We're using Androids Path mechanism here to construct an outline in memory, then call drawPath() on it to get it to appear immediately. We are also rotating the whole canvas by the amount in mAngle, just for the duration of this draw, so it appears the arrow itself has been rotated correctly.