Home > Articles > Mobile Application Development & Programming

  • Print
  • + Share This
This chapter is from the book

Recipe: Retrieving and Using Device Attitude

Imagine an iPad sitting on a desk. There’s an image displayed on the iPad, which you can bend over and look at. Now imagine rotating that iPad as it lays flat on the desk, but as the iPad moves, the image does not. It maintains a perfect alignment with the world around it. Regardless of how you spin the iPad, the image doesn’t “move” as the view updates to balance the physical movement. That’s how Recipe 1-7 works, taking advantage of a device’s onboard gyroscope—a necessary requirement to make this recipe work.

The image adjusts however you hold the device. In addition to that flat manipulation, you can pick up the device and orient it in space. If you flip the device and look at it over your head, you see the reversed “bottom” of the image. You can also tilt it along both axes: the one that runs from the home button to the camera, and the other that runs along the surface of the iPad, from the midpoints between the camera and home button. The other axis, the one you first explore, is coming out of the device from its middle, pointing to the air above the device and passing through that middle point to behind it. As you manipulate the device, the image responds to create a virtual still world within that iPad.

Recipe 1-7 shows how to do this with just a few simple geometric transformations. It establishes a motion manager, subscribes to device motion updates, and then applies image transforms based on the roll, pitch, and yaw returned by the motion manager.

Recipe 1-7. Using Device Motion Updates to Fix an Image in Space

- (void) shutDownMotionManager
{
    NSLog(@"Shutting down motion manager");
    [motionManager stopDeviceMotionUpdates];
    motionManager = nil;
}

- (void) establishMotionManager
{
    if (motionManager)
        [self shutDownMotionManager];

    NSLog(@"Establishing motion manager");

    // Establish the motion manager
    motionManager = [[CMMotionManager alloc] init];
    if (motionManager.deviceMotionAvailable)
        [motionManager
         startDeviceMotionUpdatesToQueue:
             [NSOperationQueue currentQueue]
         withHandler: ^(CMDeviceMotion *motion, NSError *error) {
             CATransform3D transform;
             transform = CATransform3DMakeRotation(
                 motion.attitude.pitch, 1, 0, 0);
             transform = CATransform3DRotate(transform,
                 motion.attitude.roll, 0, 1, 0);
             transform = CATransform3DRotate(transform,
                 motion.attitude.yaw, 0, 0, 1);
             imageView.layer.transform = transform;
     }];
}
  • + Share This
  • 🔖 Save To Your Account