Rotation Vector Sensor in Mobile Apps

Use the fused rotation-vector / device-attitude sensor to get drift-free orientation on iOS and Android.

Timothy Lindblom

Founder, Newly

The rotation vector — called "device attitude" on iOS — is the single most useful motion signal in a smartphone. It fuses the accelerometer, gyroscope and magnetometer into a quaternion that describes the device's 3D orientation in the world. AR frameworks, compass apps and 3D viewers all build on top of it.

Key Takeaways

  • Returns orientation as a unit quaternion (x, y, z, w) or roll/pitch/yaw in radians.
  • Drift-free: the magnetometer corrects yaw, the accelerometer corrects pitch and roll.
  • iOS exposes it via `CMDeviceMotion.attitude`; Android via `TYPE_ROTATION_VECTOR` (or `GAME_ROTATION_VECTOR` without the magnetometer).
  • Use it for AR, compass overlays, 360° video viewers and panorama capture UIs.

Rotation Vector at a Glance

Quaternion
x, y, z, w output
<1°
Steady-state error
50–200 Hz
AR-grade rate
Virtual
Multi-sensor fusion

What It Is & How It Works

What it is. A virtual sensor that outputs the orientation of the device as a quaternion. Internally the OS runs a Kalman / complementary filter that combines the gyroscope (fast but drifting), accelerometer (slow but absolute "down") and magnetometer (slow but absolute "north").

How it works. Subscribe to a stream and you get either a quaternion or a rotation matrix. Convert to roll/pitch/yaw with a one-line helper if you need Euler angles.

Units & signal. Quaternion components are unitless and unit-norm. Euler angles in radians (Android `getOrientation`) or degrees (iOS via small conversion).

What You Can Build With It

AR placement

Anchor virtual objects so they stay world-fixed when the device moves.

Example: A "preview furniture in your room" feature in a retail app.

Compass with tilt compensation

Use yaw from the rotation vector instead of computing heading from raw mag values.

Example: A compass that stays accurate even when held at an angle.

360° / panorama viewers

Drive the camera angle in a 3D scene directly from the device attitude.

Example: A real-estate app that lets users explore a 360° living room photo by tilting.

Stabilised camera UIs

Counter-rotate UI overlays so the horizon stays level on screen.

Example: A photography app that draws a fixed horizon line over the viewfinder.

Permissions & Setup

iOS prompts for Motion & Fitness on first use. Android requires no runtime permission, though some OEMs require enabling location services for the magnetometer to be calibrated.

iOS · Info.plist

  • NSMotionUsageDescription

Android · AndroidManifest.xml

No special permission keys required.

Code Examples

Setup

  • Expo: `npx expo install expo-sensors` (use `DeviceMotion.rotation`)
  • iOS: `CMMotionManager.startDeviceMotionUpdates(using:to:)` — pick a reference frame
  • Android: `Sensor.TYPE_ROTATION_VECTOR` (or `TYPE_GAME_ROTATION_VECTOR` without magnetometer)
import { useEffect, useState } from 'react';
import { DeviceMotion } from 'expo-sensors';

export function useAttitude() {
  const [r, setR] = useState({ alpha: 0, beta: 0, gamma: 0 });

  useEffect(() => {
    DeviceMotion.setUpdateInterval(50);
    const sub = DeviceMotion.addListener(({ rotation }) => {
      if (rotation) setR(rotation); // radians: alpha=yaw, beta=pitch, gamma=roll
    });
    return () => sub.remove();
  }, []);

  return r;
}

Tip: With Newly, you describe the feature you want and the AI agent wires up the sensor, permissions, and UI for you. Try it free.

Best Practices

  • Use quaternions internally

    Quaternions avoid gimbal lock and interpolate smoothly. Convert to Euler only for display.

  • Pick the right reference frame on iOS

    `xMagneticNorthZVertical` is the right default for compass / AR. Use `xArbitraryZVertical` if you don't care about absolute heading and don't want magnetometer dependency.

  • Use GAME_ROTATION_VECTOR when magnetometer is unreliable

    Android's `TYPE_GAME_ROTATION_VECTOR` skips the magnetometer — perfect for indoors or near interference.

  • Throttle updates for UI

    AR / 3D rendering can use 60+ Hz, but plain UI updates only need 15–30 Hz to feel smooth.

Common Pitfalls

Coordinate frame surprises

iOS, Android and OpenGL each use slightly different axes. A direct copy of values between them causes mirrored / upside-down behaviour.

Mitigation: Pick one library that normalises (Expo, Three.js, ARKit/ARCore) and stick with its conventions.

Mixing degrees and radians

Half the APIs use radians, half use degrees, and one or two report only quaternions.

Mitigation: Wrap everything in a small helper that returns one consistent unit.

Magnetometer dragging the result

Indoor or near steel, the magnetometer can yank yaw 30°+.

Mitigation: Switch to `GAME_ROTATION_VECTOR` (or iOS `xArbitraryZVertical`) for indoor scenes that don't need true north.

Forgetting devices without a magnetometer

A few cheap tablets ship without one — `TYPE_ROTATION_VECTOR` may then be unavailable.

Mitigation: Feature-detect and gracefully fall back to `GAME_ROTATION_VECTOR` or accelerometer-only tilt.

When To Use It (And When Not To)

Good fit

  • AR object placement and 3D pose tracking
  • Tilt-compensated compass and heading overlays
  • 360° image / video viewers
  • Stabilising on-screen indicators against device rotation

Look elsewhere if…

  • Step counting or activity recognition — use linear acceleration
  • Background updates on iOS without entitlement
  • Devices missing a magnetometer if you need true north
  • Computing translation — orientation only, no position

Frequently Asked Questions

What is the difference between rotation vector and quaternion?

Android's rotation vector is essentially the imaginary part of a unit quaternion. You can pass it to `getRotationMatrixFromVector` to get a usable 3x3 matrix or compute the full quaternion with one extra step.

Why does my AR scene tilt when I walk near a fridge?

Magnetic interference is corrupting the yaw correction. Switch to `GAME_ROTATION_VECTOR` (Android) or `xArbitraryZVertical` (iOS) when absolute heading isn't required.

Should I subscribe to the rotation vector or build my own fusion?

Use the platform sensor unless you have very specific needs (sub-degree pose for industrial AR). The vendor implementations are tuned for the device's chip.

Does this drift?

Pitch and roll are absolute (anchored by gravity); yaw is absolute when the magnetometer is reliable. Without a magnetometer, yaw will drift slowly — that's why `GAME_ROTATION_VECTOR` exists.

Build with the Rotation Vector on Newly

Ship a rotation vector-powered feature this week

Newly turns a description like “use the rotation vector to ar placement into a real React Native app — permissions, native modules and UI included. Full source code is yours, and you can publish to the App Store and Google Play directly from the dashboard.

Start Building Your App

Want a deeper dive on the underlying APIs? See Expo Sensors, Apple Core Motion and Android sensor framework.

Continue Learning