Archived

This topic is now archived and is closed to further replies.

Best way to do camera rotation in 3d

This topic is 5645 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I just read a tutorial on gametutorials.com on moving and rotating the camera. The way he does the calculation is this:

void CCamera::RotateView(float angle, float x, float y, float z) { CVector3 vNewView; // Get the view vector (The direction we are facing) CVector3 vView = m_vView - m_vPosition; // Calculate the sine and cosine of the angle once float cosTheta = (float)cos(angle); float sinTheta = (float)sin(angle); // Find the new x position for the new rotated point vNewView.x = (cosTheta + (1 - cosTheta) * x * x) * vView.x; vNewView.x += ((1 - cosTheta) * x * y - z * sinTheta) * vView.y; vNewView.x += ((1 - cosTheta) * x * z + y * sinTheta) * vView.z; // Find the new y position for the new rotated point vNewView.y = ((1 - cosTheta) * x * y + z * sinTheta) * vView.x; vNewView.y += (cosTheta + (1 - cosTheta) * y * y) * vView.y; vNewView.y += ((1 - cosTheta) * y * z - x * sinTheta) * vView.z; // Find the new z position for the new rotated point vNewView.z = ((1 - cosTheta) * x * z - y * sinTheta) * vView.x; vNewView.z += ((1 - cosTheta) * y * z + x * sinTheta) * vView.y; vNewView.z += (cosTheta + (1 - cosTheta) * z * z) * vView.z; // Now we just add the newly rotated vector to our position to set // our new rotated view of our camera. m_vView = m_vPosition + vNewView; }

My question is this, I don''t know how he came up with this formula. I''ve messed with sin and cos functions on the unit circle and it is fairly easy in 2d, but in 3d I don''t understand where he got this formula, or what other formula can be used to accomplish the same thing. I don''t just want to copy other peoples code, so I''m trying to find some reading material other than this, or some friendly advice on how to accomplish this.

Share this post


Link to post
Share on other sites
he''s basically rotating the camera around an axis by an angle...All the stuff you see there is basically a multiplication between a rotation matrix and the view vector, to get a new view vector. (the direction camera is pointing)

well, my advice is to thoroughly understand vectors and matrices, and then the camera code becomes easy to figure out. You might wanna look up rotation matrix for arbitrary axis. What appears here is not the computation of camera itself, but a function to rotate the current camera to another position. What you should do depend largely on API you are using.

Share this post


Link to post
Share on other sites
void tMatrix::LookAt(tVector Camera, float distance)
{
double aplha, theta;
float a, b, c, d;
tMatrix m;

aplha = atan( Camera.y / Camera.z );
theta = asin( Camera.z / distance );

a = float( sin(theta) ); b = float( cos(theta) );
c = float( sin(aplha) ); d = float( cos(aplha) );

// [ -sin(a) -cos(a)*cos(b) -cos(a)*sin(b) 0 ]
// [ cos(a) -sin(a)*cos(b) -sin(a)*sin(b) 0 ]
// [ 0 sin(b) -cos(b) 0 ]
// [ 0 0 distance 1 ]

// top line
m.mat[0] = -a;
m.mat[1] = -b*c;
m.mat[2] = -b*c;
// line 2
m.mat[4] = b;
m.mat[5] = -a*d;
m.mat[6] = -a*c;
// line 3
m.mat[9] = c;
m.mat[10] = -d;
// bottom line
m.mat[14] = distance;

Set(m * *this);
}

Share this post


Link to post
Share on other sites
Here's the matrix I use for camera rotation (well, for any rotation even), I rotate the 3 vectors of my camera with it.

This matrix rotates any vector around any other vector. For camera roll, I rotate the camera around it's own length axis, for camera pitch, I rotate it around it's width axis, and for yaw, I rotate it around the Z axis of the world.


      
vector rotateAroundArbitrary(vector v, vector l, double a)
{
/////////////////////////////////////////////////////

//Used Matrix

/////////////////////////////////////////////////////

//

// [tx²+c txy+sz txz-sy 0]

// R = [txy-sz ty²+c tyz+sx 0]

// [txz+sy tyz-sx tz²+c 0]

// [0 0 0 1]

//

// where c = cos(a), s = sin(a), t = 1-cos(a)

// l = unit vector on rotation axis

// a = angle of rotation

// x, y and z are the coordinates of v

//

// final formula: w = R*v

//

// where w = returned vector, v = given vector

//

////////////////////////////////////////////////////


vector w;

double c, s, t;

l = normalize(l);

c = cos(a);
s = sin(a);
t = 1 - c;

w.x = (t*l.x*l.x + c)*v.x + (t*l.x*l.y + s*l.z)*v.y + (t*l.x*l.z - s*l.y)*v.z;
w.y = (t*l.x*l.y - s*l.z)*v.x + (t*l.y*l.y + c )*v.y + (t*l.y*l.z + s*l.x)*v.z;
w.z = (t*l.x*l.z + s*l.y)*v.x + (t*l.y*l.z - s*l.x)*v.y + (t*l.z*l.z + c)*v.z;

w.x = w.x*length3D(v)/length3D(w);
w.y = w.y*length3D(v)/length3D(w);
w.z = w.z*length3D(v)/length3D(w);

return w;

}


EDIT = source tags

BTW I think you can ignore the length3D parts...



[edited by - Lode on July 2, 2002 4:28:03 PM]

Share this post


Link to post
Share on other sites