# Orbiting a camera around the Y axis whilst remaining up

I've been having difficulty with a problem which I thought was going to be a simple solution.

I have a camera facing downwards on a character. The can camera be lowered and when it's lowered it remains the same distance away from the character that it was (basically rotating around the X axis of the target). Now what I want it to be able to do is spin around the character on the Y axis as well, but to maintain the same distance and to remain upwards all the time. The problem I'm having is that if I do something similar to the way I did it on the X axis everything becomes a mess. First of all it doesn't remain facing up, as it spins the camera ends up upside down and i'm not really sure how to recalculate the up vector for it. But ontop of that it doesn't maintain the same distance from the character at all times.

This is what I have right now:

        cameraUp = new Vector3(0, 1, 0);
cameraPosition = new Vector3(cameraOffset.X, cameraOffset.Y, cameraOffset.Z);
cameraPosition = Vector3.Transform(cameraPosition - cameraTarget, Matrix.CreateFromAxisAngle(Vector3.UnitX, tippingAngle)) + cameraTarget;

//This is the part that I'm having difficulty with, the rest works fine.
cameraPosition = Vector3.Transform(cameraPosition, Matrix.CreateFromAxisAngle(Vector3.UnitY, rotationAngle));

view = Matrix.CreateLookAt(cameraPosition, cameraTarget, cameraUp);


EDIT:

Thank you to everyone, all of your comments helped. The biggest issue was that somehow I let it slip past that the cameraUp value was wrong, I think it happened as a typo when I was tidying the code up. Anyway, after fixing that the code above was exactly what I needed. I had tried that before but because the up vector was wrong I was getting really weird results so thanks to everyone. :)

• shouldn't cameraUp = new Vector3(0, 0, -1); be cameraUp = new Vector3(0, 1, 0); if you want Y+ to be up (assuming y is your horizontal axis). – PeterT Aug 17 '13 at 21:39
• So it's an orbital camera, but broken somehow? Have you checked into orbit or arcball cameras yet? They do what I think what you're talking about, which is to always look at the focus point but allow going up and down and around in a sphere and at a set distance away. – Patrick Hughes Aug 17 '13 at 21:41
• Also, make sure that you are in a coordinate system relative to your Target. Looking at the code it looks like cameraPosition is in world-space before the comment. So you need to do cameraPosition = Vector3.Transform(cameraPosition -cameraTarget, Matrix.CreateFromAxisAngle(Vector3.UnitY, rotationAngle)) + cameraTarget;. Just like with the X rotation. – PeterT Aug 17 '13 at 21:48

//This is the part that I'm having difficulty with, the rest works fine. cameraPosition = Vector3.Transform(cameraPosition, Matrix.CreateFromAxisAngle(Vector3.UnitY, rotationAngle));

Yes, I can see the problem. On this line, you are orbiting the camera's position around the world origin instead of the center of your arc's sphere (which is your camera target). You need to translate the position/target system to the world origin, do the rotation, then translate them back like you did in the first rotation to set the pitch.

try this:

//This is the part that I used to have difficulty with, but now works fine.
cameraPosition = Vector3.Transform(cameraPosition - cameraTarget, Matrix.CreateFromAxisAngle(Vector3.UnitY, rotationAngle)) + cameraTarget;


Edit: Additionally, you can combine the 2 rotations into one Vector3.Transform() like this:

Vector3 axisAngle = (Vector3.UnitX * tippingAngle) + (Vector3.UnitY * rotationAngle);
float angle = axisAngle.Length();
Vector3 axis = axisAngle / angle;//normalizes the axis
cameraPosition = Vector3.Transform(cameraPosition - cameraTarget, Matrix.CreateFromAxisAngle(axis, angle)) + cameraTarget;

• Thanks to everyone, that worked once I fixed the up vector which another comment mentioned. – user1157885 Aug 18 '13 at 1:18