I'm implementing a touch screen interface whereby the user dragging their finger on the screen will rotate the camera in a sphere around the central point.

My code works well for the horizontal swipe (rotation around the y axis), but only covers a smaller angle from the vertical swipe (rotation around the x axis) instead of the full 360. I used the article - Spherical coordinate system form Wikipedia (http://en.wikipedia.org/wiki/Spherical_coordinate_system), specifically the Cartesian Coordinates section, to do this. I've posted my code below. Can anyone help get this working through the full 360 degrees on both axis? See how Google Earth works when you swipe the globe for what I want.

This must have been done a billion times, but Google searches confuse with the phone built in camera, gps and the like. Thanks!

//Get current position
oldX = getPosition().x;
oldY = getPosition().y;
oldZ = getPosition().z;

//convert to inclination/azimuth
camRadius = Math.sqrt((oldX * oldX) + (oldY * oldY) + (oldZ * oldZ));
inclinationTheta = Math.acos(oldZ / camRadius);
azimuthPhi = Math.atan2(oldY,oldX);


//use touch screen changes (deltaTouchX and Y)
inclinationTheta = (inclinationTheta + deltaTouchScreenX) % (2 * pi);
azimuthPhi = (azimuthPhi + deltaTouchScreenY) % (2 * pi);

//get new co-ordinates
newX = camRadius * Math.sin(inclinationTheta) * Math.cos(azimuthPhi);
newY = camRadius * Math.sin(inclinationTheta) * Math.sin(azimuthPhi);
newZ = camRadius * Math.cos(inclinationTheta);

//set new position
setPosition(newX, newY, newZ);
  • \$\begingroup\$ Yes, for some reason this topic has fallen into a search black hole. \$\endgroup\$ – user39022 Nov 25 '13 at 12:16

I've decided to rotate the objects in the scene, instead of the camera. It works almost as I want. Those articles where a bit beyond my abilities.

float oldX =  myObject.getX();
float oldZ =  myObject.getZ();

float newX = (float) (oldZ * Math.sin(rotationAngleY) + oldX * Math.cos(rotationAngleY));
float newZ = (float) (oldZ * Math.cos(rotationAngleY) - oldX * Math.sin(rotationAngleY));


float oldY =  myObject.getY();
oldZ =  myObject.getZ();

float newY = (float) (oldY * Math.cos(rotationAngleX) - oldZ * Math.sin(rotationAngleX));
newZ = (float) (oldY * Math.sin(rotationAngleX) + oldZ * Math.cos(rotationAngleX));


oldX =  myObject.getX();
oldY =  myObject.getY();

newX = (float) (oldX * Math.cos(rotationAngleZ) - oldY * Math.sin(rotationAngleZ));
newY = (float) (oldX * Math.sin(rotationAngleZ) + oldY * Math.cos(rotationAngleZ));


Not the answer you're looking for? Browse other questions tagged or ask your own question.