Направление камеры устройства, исключая альбомную / книжную ориентацию устройства - PullRequest
4 голосов
/ 03 марта 2020

Мне нужно получить направление передней камеры, исключая ориентацию устройства (альбомная / портретная). Я попытался представить это с помощью Core Motion и доступа к устройству. Здесь я попытался получить доступ к углам Эйлера и исключить отклонение от курса, однако, похоже, это не сработает, так как при повороте устройства более чем на одно значение угла Эйлера изменяется. Я также рассматриваю возможность использования кватернионов ориентации, но у меня нет опыта их использования. Мне нужна эта информация в последовательном порядке, так как позже мне нужно будет определить, направлена ​​ли камера на другое устройство в том же направлении (это может быть iOS или Android).

Повторюсь: если пользователь направляет свою телефонную камеру (основная камера, а не собственная ie одна) на статую свободы, каким будет лучший способ кодирования этой информации, независимо от того, удерживает ли пользователь телефон в портретной или альбомной ориентации, чтобы, если другой пользователь находился в том же месте, он знал, в каком направлении направить камеру?

Ответы [ 3 ]

2 голосов
/ 09 марта 2020

Я считаю, что для достижения этого вы можете использовать CLLocation. Поскольку ваша основная цель состоит в том, чтобы найти кардинальную точку , на которую указывает телефон, вы можете сделать такие вещи, как:

fun locationManager(_ manager: CLLocationManager, didUpdateHeading heading: CLHeading) {
   let angle = newHeading.trueHeading.toRadians // convert from degrees to radians
   // do what you please with this information
}

Как указано в в этом руководстве :

Значение trueHeading - это угол между этим вектором и вектором, начинающийся с той же точки, но указывающий на истинный север. Если ваш телефон точно указывает на Истинный Север, вы получите курс 0 (ноль) градусов, если он будет указывать на Восток, вы получите 90 градусов и c.

Теперь, как указано здесь , ориентация устройства может вызвать некоторые проблемы:

К сожалению, если пользователь ориентирует устройство в альбомном режиме, сообщаемые заголовки будут неправильными или, по крайней мере, будут выглядеть неправильно пользователю. Это станет особенно важным, когда вы посмотрите на интерфейсы дополненной реальности позже в этой книге; такие интерфейсы обычно отображаются в режиме альбомной ориентации.

НО! Существует решение этой проблемы:

И вы можете использовать что-то вроде этого для получения искомого заголовка:

-(float)magneticHeading:(float)heading 
        fromOrientation:(UIDeviceOrientation) orientation {

    float realHeading = heading;
    switch (orientation) {1
          case UIDeviceOrientationPortrait:
               break;
          case UIDeviceOrientationPortraitUpsideDown:
               realHeading = realHeading + 180.0f;
               break;
          case UIDeviceOrientationLandscapeLeft:
               realHeading = realHeading + 90.0f;
               break;
          case UIDeviceOrientationLandscapeRight:
               realHeading = realHeading - 90.0f;
               break;
          default:
               break;
    }
    while ( realHeading > 360.0f ) {
          realHeading = realHeading - 360;
    }
    return realHeading;
}

Извините за разные языки (Swift - Цель C), но чтобы полностью понять проблему и найти полное решение, я бы порекомендовал прочитать в источниках:

Надеюсь, это поможет! Дайте мне знать.

0 голосов
/ 12 марта 2020

В android я использую метод setRotation () для гниения камеры.

setRotation(camera, parameters, requestedCameraId);

private void setRotation(Camera camera, Camera.Parameters parameters, int cameraId) {
    WindowManager windowManager =
            (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
    int degrees = 0;

    //get current display rotation
    int rotation = windowManager.getDefaultDisplay().getRotation();

    switch (rotation) {
        case Surface.ROTATION_0:
            degrees = 0;
            break;
        case Surface.ROTATION_90:
            degrees = 90;
            break;
        case Surface.ROTATION_180:
            degrees = 180;
            break;
        case Surface.ROTATION_270:
            degrees = 270;
            break;
        default:
            Log.e(TAG, "Bad rotation value: " + rotation);
    }

    CameraInfo cameraInfo = new CameraInfo();
    Camera.getCameraInfo(cameraId, cameraInfo);

    int angle;
    int displayAngle;
    if (cameraInfo.facing == CameraInfo.CAMERA_FACING_FRONT) {
        angle = (cameraInfo.orientation + degrees) % 360;
        displayAngle = (360 - angle) % 360; // compensate for it being mirrored
    } else {  // back-facing
        angle = (cameraInfo.orientation - degrees + 360) % 360;
        displayAngle = angle;
    }

    // This corresponds to the rotation constants.
    // mRotation = angle / 90;

    camera.setDisplayOrientation(displayAngle);
    parameters.setRotation(angle);
}

Надеюсь, это работа для вас.

0 голосов
/ 03 марта 2020

Существует 4 типа из них. один устаревший:

  1. publi c stati c final int ORIENTATION_UNDEFINED = 0;
  2. publi c stati c final int ORIENTATION_PORTRAIT = 1;
  3. publi c stati c final int ORIENTATION_LANDSCAPE = 2:
  4. @ Устаревшие publi c stati c final int ORIENTATION_SQUARE = ​​3;

Вы можете учиться с

val orientation: Int = resources.configuration.orientation

Если вы хотите узнать конкретные c угол и положение, вы должны использовать Сенсор с this.sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager

и для точного положения

sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR)?.let { this.rotationVector = it}

этот класс также имеет различные функции, такие как.

TYPE_ACCELEROMETER

Измеряет силу ускорения в м / с2, которая применяется к устройству на всех трех физических осях (x, y и z). ), включая силу тяжести.

Обнаружение движения (встряхивание, наклон и т. д. c.).

TYPE_GRAVITY

Измеряет силу тяжести в м / с2, которая применяется к устройство по всем трем физическим осям (x, y, z).

Обнаружение движения (встряхивание, наклон и т. д. c.).

TYPE_GYROSCOPE

Измеряет скорость вращения устройства в рад / с вокруг каждой из трех физических осей (x, y и z).

Обнаружение вращения (вращение, поворот и т. Д. c.).

TYPE_LINEAR_ACCELERATION

Измеряет силу ускорения в м / с2, которая применяется к устройству по всем трем физическим осям (x, y и z) без силы тяжести.

Контроль ускорения вдоль одна ось.

TYPE_ROTATION_VECTOR

Измеряет ориентацию устройства, предоставляя три элемента вектора вращения устройства.

Обнаружение движения и обнаружение вращения.

...