Best way to do camera rotation in 3d

Started by
2 comments, last by xg0blin 21 years, 9 months ago
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.
Advertisement
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.
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);
}
I burn cold
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]

This topic is closed to new replies.

Advertisement