First, let us discuss the dot product of two vectors. 
The dot product of two vectors u and v is defined as: x = u1*v1 + u2*v2 + ... + un*vn 
Example: Vector u = (3, 5, 7) and Vector v = (2, 4, 6) 
Then 
x = 3*2 + 5*4 + 7*6 
x = 6 + 20 + 42 
x = 68 
x (that is, 68) is then the dot product of vectors u and v. 
Note, the dot product is represented as u.v
  
The dot product is part of a formula for finding the angle between two vectors. 
That formula is: 
Cos( Theta ) = u.v / ||u|| ||v|| 
That is, the dot product of u and v over the magnitude of u times the magnitude of v.
  
This can be very useful. Imagine using this formula for particles in a first person shooter. 
The particle position can pose as the origin. The default direction that the particles face 
can be used for one vector. The direction towards the camera from the particle can be used 
as the second vector. Thus far, this gives us the following: 
Vector u(0, 0, -1) //facing down the z axis by default
Vector v(cam.x - particle.x, 0, cam.z - particle.z) //cam's position relative to particle 
Normalize(v) //normalization of a vector involves dividing each component of the vector by 
its magnitude. Length of a vector is defined as the square root of the sum of the squares of 
each of the vector's components. That is: sqrt(v.x*v.x + v.y*v.y + v.z*v.z)  Therefore, 
the normal of a vector is defined as: 
Magnitude = sqrt(v.x*v.x + v.y*v.y + v.z*v.z) 
Normal = (v.x/Magnitude, v.y/Magnitude, v.z/Magnitude)
  
Now then, with vectors u and v from above being our vectors representing the directions from 
the origin (that is, the particle's default position), we can use the formula from above to 
determine how much we must rotate a particle to make it face the camera.
  
This leads us to the final steps of this sample. 
Vector u(0, 0, -1) 
Vector v(cam.x - particle.x, 0, cam.z - particle.z) 
UMagnitude = sqrt(u.x*u.x + u.y*u.y + u.z*u.z) 
VMagnitude = sqrt(v.x*v.x + v.y*v.y + v.z*v.z) 
Vector VNormal(v.x/VMagnitude, v.y/VMagnitude, v.z/VMagnitude) 
DotProduct = u.x*v.x + u.y*v.y + u.z*v.z 
Theta = DotProduct / (UMagnitude * VMagnitude)
  
All that remains is to rotate the particle by the arccosine of Theta. 
Because cosine oscillates between -1 and 1 (and because the result of the formula is 
Cosine Theta), this method can get angles up to 180 degrees. This gives us two scenarios for 
billboarding: angle = 0 to 179 degrees, and angle = 180 to 359 degrees.
  
Because this is strictly math, this can be applied to all graphics programming regardless of 
the library or API being used. However, because I am a fan of DirectX, the code supplied in 
the sample uses DirectX.
  
 
D3DXMATRIX GetBillboardMatrix(D3DXVECTOR3 position, D3DXVECTOR3 cam){ 
    //local variables 
    D3DXMATRIX World;                    //returned after built 
    D3DXMATRIX Scalar;                    //scalar matrix 
    D3DXMATRIX RotY;                    //billboard particles 
    D3DXMATRIX RotZ;                    //roll particles 
    D3DXMATRIX Translate;                    //move particles 
    D3DXVECTOR3 u(0.0f, 0.0f, -1.0f);            //unrotated direction of particles 
    D3DXVECTOR3 v = cam;
  
    //v = direction from origin to cam 
    v.x -= particles.position.x;                //subtract particle position to get 
    v.y = 0.0f;                        //cam position from origin 
    v.z -= particles.position.z; 
    D3DXVec3Normalize(&v, &v);
  
    //get dot product and magnitude of u and v 
    float theta = u.x*v.x + u.y*v.y + u.z*v.z;        //get dot product of u and v (Horizontal angle) 
    float umag = sqrt( (u.x*u.x) + (u.y*u.y) + (u.z*u.z) );    //magnitude of u 
    float vmag = sqrt( (v.x*v.x) + (v.y*v.y) + (v.z*v.z) );    //magnitude of v
  
    //get angle between vectors u and v 
    theta = acos(theta / (umag*vmag));            //cos theta = (u . v) / ||u|| ||v||
  
    //set all matrices to identity matrix 
    D3DXMatrixIdentity(&World); 
    D3DXMatrixIdentity(&Scalar); 
    D3DXMatrixIdentity(&RotY); 
    D3DXMatrixIdentity(&RotZ); 
    D3DXMatrixIdentity(&Translate);
  
    //scale particles to desired size 
    D3DXMatrixScaling(&Scalar, particles.scale.x, particles.scale.y, particles.scale.z);
  
    //rotate particles around y axis to make them face camera horizontally 
    if(cam.x >= particles.position.x) 
        D3DXMatrixRotationY(&RotY, -theta);        //180 to 359 degrees 
    else 
        D3DXMatrixRotationY(&RotY, theta);        //0 to 179 degrees
  
    //rotate around z axis to make particles roll 
    D3DXMatrixRotationZ(&RotZ, roll);
  
    //move particles to their positions 
    D3DXMatrixTranslation(&Translate, particles.position.x, particles.position.y, particles.position.z); 
  
    //multiply all matrices into final world matrix 
    D3DXMatrixMultiply(&World, &World, &Scalar);        //size 
    D3DXMatrixMultiply(&World, &World, &RotZ);        //z first to let particles roll 
    D3DXMatrixMultiply(&World, &World, &RotY);        //y to make particles face camera 
    D3DXMatrixMultiply(&World, &World, &Translate);        //move particles to their positions
  
    //return final world matrix 
    return World; 
} 
 
 |