Search code examples
androidcompass-geolocationrotateanimation

android compass rotateanimation


I'm making a compass that points to a user defined location. I'm using the rotateanimation to rotate the needle. When the needle points in the direction of the phone I know the phone is pointing in the direction I want. However, I wanted the needle to point in the correct direction irregardless of the phone's azimuth.

The problem is that it seems that rotateanimation does not rotate the needle according to the real world coordinates, and instead is relative to the phone's screen. So a 58 degree rotation of the needle does not match a 58 degree rotation in the real world. Is this true or am I making a mistake in my code?

The compass is meant to be used by placing the phone's back flat on a surface. I've also tried outputting the azimuth and it reads like this:

Azimuth           Actual Phone angle
0                        0
45                       90
90                       180

when it gets close to a full circle back it bounces between 120 and 340.

Here's the code:

direction = 360 - azimuth + rotate;

RotateAnimation animate = new RotateAnimation(rotateLast, direction, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
            animate.setFillAfter(true);
            animate.setInterpolator(new LinearInterpolator());
            animate.setDuration(10);
            needle.startAnimation(animate);

            rotateLast = direction;

azimuth is the phone's azimuth from the sensor, rotate is the user specified direction (in degrees from north), and direction is the required rotation of the needle.

rotateLast is the last position the needle was at, I'm using this because without it the needle reverts to zero degrees and flickers.

Thanks, P.S. this has been driving me crazy


Solution

  • I figured it out, my math was all wrong and I misunderstood how azimuth affected the rotation.

    I realized when I rotated the image to just azimuth and understood that it resulted in the needle pointing north. All I needed to do was just add the user direction. The math I was using caused the needle to rotate in unpredictable ways.

    The answer is simply:

    RotateAnimation animate = new RotateAnimation(-azimuth+rotation, -azimuth+rotation, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
    

    the -azimuth is because of how rotateanimation rotates counter-clockwise.