Back

Technologies:

javascript
Tolerim
21 hours ago

### How can I convert Safari's device orientation to absolute device orientation?

My goal is to develop an AR application utilizing THREE.js, and my current task is to determine how to position the camera concerning the earth. While Android provides access to absolute orientation, Safari only provides orientation values relevant to an arbitrary point and a compass heading, which specifies the angle at which the phone's top points in the X and Z plane. I am attempting to determine how to convert relative orientation to absolute orientation using this compass heading.

Through utilizing `window.event('deviceorientation'` and applying a bit of geometry, I have discovered how to rotate the camera in accordance with the device's orientation. However, attempts to eliminate the Y-axis orientation and add the compass heading angle along the axis have resulted in unnecessary camera rotation. The "bit of geometry" was accomplished with the following code:

``````const offset = new THREE.Quaternion().setFromAxisAngle(
new THREE.Vector3(-1, 0, 0),
Math.PI / 2
);

const eulerOrientation = new THREE.Euler(beta, alpha, -gamma, "YXZ")

return new THREE.Quaternion().setFromEuler(eulerOrientation).multiply(offset)
``````
Tolerim
21 hours ago
To convert the relative orientation to absolute orientation based on compass heading, you can use the following steps: 1. Get the device's orientation using window.event('deviceorientation'). 2. Extract the compass heading value from the orientation data. 3. Rotate the THREE.js camera according to the compass heading angle around the Y-axis using camera.rotation.y. 4. Apply the remaining rotation around the X-axis and Z-axis using the "bit of geometry" code you have already implemented. Here's an example code snippet:
``````function handleDeviceOrientation(event) {
// Extract orientation data
const { beta, alpha, gamma } = event;

// Rotate camera around Y-axis
camera.rotation.y = (heading / 180) * Math.PI;

// Apply remaining rotation using "bit of geometry" code
const offset = new THREE.Quaternion().setFromAxisAngle(
new THREE.Vector3(-1, 0, 0),
Math.PI / 2
);
const eulerOrientation = new THREE.Euler(
beta,
alpha,
-gamma,
"YXZ"
);
const absoluteOrientation = new THREE.Quaternion()
.setFromEuler(eulerOrientation)
.multiply(offset);
camera.quaternion.copy(absoluteOrientation);
}