Device camera direction excluding device landscape/portrait orientation

user426132 :

I need to get the direction of the front facing camera excluding the devices orientation (landscape/portrait). I tried to represent this using Core Motion and accessing device attitude. Here I tried to access the Euler angles and exclude the yaw, however this doesn't seem to work as when rotating the device more that one Euler angle value changes. I am also considering using the orientation quaternion but I don't have experience using them. I need this information in a serialisable manner as I would later need to determine if a different device has it's camera pointed in the same direction ( this device may be either iOS or Android).

To reiterate: if a user is pointing his phone camera (main camera not selfie one) towards the statue of liberty, what would be the best way to encode this information regardless if the user is holding the phone in portrait or landscape, such that if another user is in the same location he would know the direction in which to point his camera?

rusito23 :

I believe that in order to achieve this, you can use CLLocation. As you main objective is to find the cardinal point towards which the phone points, you can do things like:

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

As stated in this tutorial:

The trueHeading is the angle between that vector and the vector starting from the same point but pointing towards the true north. If your phone points exactly to the True North you’ll get a heading of 0 (zero) degrees, if it points towards East you’ll get 90 degrees etc.

Now, as stated here, the device orientation can cause some trouble:

Unfortunately, if the user orientates the device into Landscape Mode, the reported headings will be incorrect, or at least look incorrect to the user. This will become especially important when you look at augmented reality interfaces later in the book; such interfaces are generally viewed in Landscape Left mode.

BUT! There is a solution for this problem:

And you can use something like this to retrieve the heading you are looking for:

-(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;
}

Sorry about the different languages (Swift - Objective C), but in order to fully understand the problem and find a complete solution I would recommend to read into the sources:

Hope this helps! Let me know.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=220083&siteId=1