Как получить телефон в дополненной реальности?
Возможный дубликат: Android getOrientation Азимут загрязняется при наклоне телефона
Я новичок в разработке Android, и я пытаюсь заставить пользователя столкнуться.
После поиска в Интернете я уверен, что мне нужно использовать remapCoordinateSystem
Документация Android говорит, что это хорошо для приложения дополненной реальности.
Я стараюсь использовать существующий код, чтобы быть уверенным, что это хороший способ.
(Наконец-то я хочу создать приложение с дополненной реальностью)
Следующий код должен возвращать пользователя в степени:
Код:
Sensor sensor = event.sensor;
if (sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
gravity = event.values.clone();
}else if (sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
geomagnetic = event.values.clone();
}
if (gravity != null && geomagnetic != null){
_rM = SensorManager.getRotationMatrix (R, null, gravity, geomagnetic);
if(_rM){
int mScreenRotation = activity.getWindowManager().getDefaultDisplay().getRotation(); // get user orientation mode
switch (mScreenRotation) { // Handle device rotation (landscape, portrait)
case Surface.ROTATION_0:
axisX = SensorManager.AXIS_X;
axisY = SensorManager.AXIS_Y;
break;
case Surface.ROTATION_90:
axisX = SensorManager.AXIS_Y;
axisY = SensorManager.AXIS_MINUS_X;
break;
case Surface.ROTATION_180: // not handled by my phone so I can't test
axisX = SensorManager.AXIS_MINUS_X;
axisY = SensorManager.AXIS_MINUS_Y;
break;
case Surface.ROTATION_270:
axisX = SensorManager.AXIS_MINUS_Y;
axisY = SensorManager.AXIS_X;
break;
default:
break;
}
SensorManager.remapCoordinateSystem (R, axisX, axisY, outR);
SensorManager.getOrientation (outR, gO);
}
}
userFacing = (float) Math.toDegrees(gO[0]); // Radian to degree
if(userFacing<0) { userFacing+=360; } // -180;180 to 0;360
return userFacing;
На самом деле я могу получить точный компас, когда телефон направлен вниз, но когда я пытаюсь переместить телефон (как это сделал бы пользователь), результаты очень неточные: когда я наклоняю устройство, направление может сместиться на 40°...
Я видел эту ссылку: /questions/6919993/android-sensormanager-stranno-kak-perenaznachit-sistemu-koordinat
Но если я останусь в наклоне, результаты снова будут неточными (это среднее значение, поэтому это нормально!) И мне нужно, чтобы компас работал в любое время...
Я думаю, что я буду использовать TYPE_GYROSCOPE
, но не все устройства имеют гироскоп в настоящее время, поэтому мне нужно другое решение для всех других устройств!
Надеюсь, вы понимаете мою проблему, и извините за мой плохой английский! (Я француз)
Решение
Итак, после адаптации приложения на iOS, я решил проверить, были ли методы Android такими же хорошими, как и я. Месяц назад я опубликовал решение, и оно было действительно неправильно. Я сделал огромную ошибку remapCoordinateSystem
: Я использовал AXIS_X
а также AXIS_Y
чтобы получить мою матрицу, и я попытался исправить свои значения с другими значениями. Как предложил @HoanNguyen, мы просто должны использовать AXIS_X
а также AXIS_Z
и Android справится с остальным.
Итак, вот окончательный код. Гораздо короче и проще:
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
gravity = lowPass(event.values.clone(), gravity);
}
else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
geomagnetic = lowPass(event.values.clone(), geomagnetic);
}
if (geomagnetic != null && gravity != null) {
if (SensorManager.getRotationMatrix (R_in, null, gravity, geomagnetic)) {
SensorManager.remapCoordinateSystem (R_in, SensorManager.AXIS_X, SensorManager.AXIS_Z, R_out);
SensorManager.getOrientation (R_out, gO);
}
}
И чтобы получить магнитный север, вы просто должны использовать gO[0]
лайк heading = gO[0];
(Внимание, возвращаемые значения в радианах)
Надеюсь, что здесь кто-то может!
1 ответ
И ваш код, и решение, которое вы нашли, неверны, если под "лицом к телефону" вы подразумеваете противоположное направление z-координаты устройства. Для дополненной реальности, вы просто звоните
remapCoordinateSystem(inR, AXIS_X, AXIS_Z, outR);
не зависит от ориентации устройства. Затем азимут в вызове getOrientation() дает направление телефона, обращенное относительно Магнитного Севера.
Эти 2 вызова составляют проекцию z-координаты устройства на плоскость XY мировых координат, а затем вычисляют направление результирующего вектора.