Reputation: 686
I want to get the degree of Rotation of all three axis. I am trying to achieve with landscape mode. When rotate device from left to right (Y-rotation), I want the degree covered once user set a left end and rotatae to right. So we need the degree 360 when it reached the starting point. So for the y-rotation, using the following calculation and it is fine.
let q = sceneView.pointOfView.orientation
let yRotation = Float.pi - atan2f( (2*q.y*q.w)-(2*q.x*q.z), 1-(2*pow(q.y,2))-(2*pow(q.z,2)) )
Ref: Getting the rotation of device around the world origin's y axis in ARKit
Similarly, want the Z-rotation, for Z-rotation , no need for 360 degree rotation. But need accurate value when rotate about upto 90 degree This is fine if we use the
var zRotation = sceneView.pointOfView.eulerAngles.z
But this will be wrong* if we rotate the device on left to right (Y-direction ) some degree and then check the Z rotation, we will get the Z-rotation values as near to 180 degree rather than near to 0
So tried a bad way to get the Z rotation like:
var zRotation = sceneView.pointOfView.eulerAngles.z
if abs(sceneView.pointOfVieweulerAngles.z.toDegree) > 90 {
zRotation = (abs(cameraNode.eulerAngles.z.toDegree) - 180).toRadian
}
But this is not accurate, we can see a jumb the Z-rotation value when subtracting 180.
Could you suggest a proper method..
X-rotation value is simialr to Z-rotation, getting values near to 180 when check after rotate left to right (Y-rotation) some degree.
Thanks
Edited: Sep 3, 2109 For x and y, Now I am using
let xRotation = sceneView!.session.currentFrame!.camera.eulerAngles.x
let zRotation = sceneView!.session.currentFrame!.camera.eulerAngles.z
Upvotes: 4
Views: 1989
Reputation: 383
If you disable the landscape orientation (left & right), you will get pretty good data for x, y and z rotation.
if let q = self?.sceneView.pointOfView?.orientation {
let heading = atan2f( (2 * q.y * q.w) - (2 * q.x * q.z), 1 - (2 * pow(q.y,2)) - (2 * pow(q.z,2)) )
let attitude = asinf( (2 * q.x * q.y) + (2 * q.z * q.w) )
let bank = atan2f( (2 * q.x * q.w) - (2 * q.y * q.z), 1 - (2 * pow(q.x,2)) - (2 * pow(q.z,2)) )
print("X: \(attitude * (180.0 / .pi)) Y: \(heading * (180.0 / .pi)) Z: \(bank * (180.0 / .pi))")
}
If you allow Landscape Orientation then you will get different values. Once the device goes from Portrait to Landscape, you will get rotation data as if the whole coordinate space has been rotated by pi/2 radians. Then you have to tweak the data (Add or Substract pi/2) to get correct values. Is there a way to convert the coordinate system after a change to Landscape Orientation?
So if you don't want your device window to rotate with orientation, disselect the Landscape mode. Though you can get all orientation info to perform any UI changes:
if UIDevice.current.orientation == UIDeviceOrientation.faceUp {
print("faceUp")
} else if UIDevice.current.orientation == UIDeviceOrientation.landscapeRight {
print("landscapeRight")
} else if UIDevice.current.orientation == UIDeviceOrientation.portrait {
print("portrait")
} else if UIDevice.current.orientation == UIDeviceOrientation.portraitUpsideDown {
print("portraitUpsideDown")
}
Upvotes: 2