Locating an iPhone in 3D space

A world of augmented reality possibilities were opened up once the capability to superimpose graphics over the camera display was made available by Apple. One of my initial game ideas required this functionality, but it’s been a case of “wait for a tutorial to show how to do this and miss the boat” versus “spend a lot of time working on inventing new functionality instead of doing other things that you really should be working on”. Obviously, I would prefer to do the latter over the former…

One caveat: right now, I do not have a working solution. The following is a description of what I’m working through to solve this problem – and any advice would be greatly appreciated!

Game concept

My game idea didn’t involve technology as much as a concept of what I wanted the players to “feel” when they played it – the sort of fully immersive game where you feel like you are “in” the game world, and you have physical reactions (heart pounding, adrenaline spiking) like you would if it was real life. This meant that the game would have to involve the use of the space around you, in order to psychologically simulate the idea of fear and accomplishment. The example I came up with was a simple “ghost hunter” game – very similar in concept to the way Ghostbusters trapped ghosts – crossed with the real-life apprehension you have playing Laser tag or paintball.

One player would start a game (similar to starting a game in a multiplayer shooter like Quake or Unreal Tournament). This would create a series of enemies located somewhere in 3D space around them, which they’d have to avoid, as well as capture and trap. Other players would then be able to “join” their game (via peer-to-peer networking), in which case they’d see the enemies in the same exact physical 3D locations, but adjusted relative to the 3D location of their phones.

The following image shows how two iPhones (or iPod Touches) would view an object (the green cube).

multiple iphones in 3D space

Each iPhone has its own viewing angle and would see the object as located in the same physical space, but they would display it relative to their own position. For example, the iPhones listed above would show the following screens:

view from perspective of first iPhone view from perspective of second iPhone

The gameplay would involve locating and then choosing to “capture” a ghost – but two or more players would be required to lock on in order to capture a ghost. However, if a ghost intersects with the 3D space located by a device, it would “kill” the device – basically booting them out of the game. In my mind, that would create a situation with people ducking and bobbing around trying to get away from a “ghost” that seems to be following them in real life…and it would give the feeling of a real ephemeral entity that you can’t see – but is right in front of you. The blurring of what is real and what is virtual (making it seem that the iPhone is acting like an infrared camera for ghosts) would have a really creepy effect, and would be perfect for a horror-style game (especially when you add intense graphics, things moving and tracking you, objects given 20% alpha blends so they merge with the background, etc.)

Augmented Reality Implementation in 3D Space

In order to implement this game, I need to be able to locate a device in 3D space, and display an object relative to the device itself.

cube view of iPhone in 3D space with annotations for use in augmented reality

Let’s start with the easy part. Latitude and longitude are given through the CLLocationManager (for the device’s location), and CLLocation:getDistanceFrom: to measure the distance between the current location and the location of any other objects.

We also need to know where the device is pointed (there is a different view when you’re facing forward versus facing backward). The magnetometer will give us the compass direction, which we can use to adjust where other objects are in 3D space.

We still have two more things we need to know where we are in 3D space. One is the vertical viewing angle (the viewing area will be different if we’re pointed at the ceiling, versus pointed at the floor). I was planning on using the accelerometer to help me figure out this angle based on default values (either perfectly horizontal (parallel to the floor) or perpendicular to the floor).

diagram showing three iPhone viewing angles

The one final variable that I need (and the one I don’t think I can get) is the height of the iPhone from the floor. From what I’ve seen, other iPhone augmented reality applications ignore this, and assume a fixed distance from the floor (for argument’s sake, let’s arbitrarily call it 1 meter). The problem with this is that I wouldn’t be able to have ghosts hide up by the ceiling or down on the floor – everything would effectively be in the same plane view, which means simple rotating 360 degrees would show the full game area (and would greatly decrease the difficulty, challenge, and intensity of the game).

As much as I don’t like posting problems without solutions, this is a problem that I’ve been playing with for the past few months and I didn’t want to sit on it any longer. If you have any suggestions for what I should do, please post them in the comments!


About jeffrey

Jeffrey Berthiaume is a multimedia developer and internet architect who has designed and built award-winning websites, kiosks, and content management systems. He bridges the gap between creative and technology with an ability to balance the needs of designers and marketing with the capabilities of existing technology.
This entry was posted in iOS, Tutorials. Bookmark the permalink.

One Response to Locating an iPhone in 3D space

  1. William Hu says:

    Hey Jeffrey, how about let people set a height of him/role, and may be you can divide by 2 to get it?

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>