I have 2 points (Android Location objects): current location and target location. Also I have a direction (in degrees) of my device.
I wanna calculate an angle between target location and direction. How to do it properly?
I receiving location from FusedLocationProvider (if it's matter). Now i just use
float requiredAngle = Math.abs(location.getBearing() - 180 - target.bearingTo(location));
float angleBetween = Math.abs(requiredAngle - location.getBearing());
and it's returns incorrect angle.
I think I should caclate the difference between true north and magnetic north and add device direction. Then use currentPosition.bearingTo(target), and subtract device direction from bearing.
This angle called relative bearing.
Register listeners to Sensor.TYPE_ROTATION_VECTOR, Sensor.TYPE_ACCELEROMETER, Sensor.TYPE_MAGNETIC_FIELD. Like:
sensorManager.registerListener(listener, sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR), SensorManager.SENSOR_DELAY_NORMAL);
Then make a listener for this:
private float[] gravity;
private float[] geomagnetic;
private float[] R = new float[9];
private float[] I = new float[9];
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
gravity = sensor.values(); // Just save the values
}
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
geomagnetic = sensor.values();
}
if (SensorManager.getRotationMatrix(R, I, gravity, geomagnetic)) { // If something is wrong (like device is in free fall)
float orientation[] = new float[3];
SensorManager.getOrientation(R, orientation);
// Now you have values from -PI to PI
float heading;
if (R[0] > 0) { // R[0] is heading
heading = R[0] * 180 / PI;
} else { // -PI, eq. from South to West to North
heading = (Math.abs(R[0]) * 180 / PI) * 2;
}
float relativeBearing = location.bearingTo(target) - heading;
if (relativeBearing < 0) {
relativeBearing = 360 + relativeBearing;
}
}
}
Documentation: https://developer.android.com/reference/android/hardware/SensorManager#getRotationMatrix(float[],%20float[],%20float[],%20float[]) https://developer.android.com/reference/android/hardware/SensorManager#getOrientation(float[],%20float[])