[Math] 3D Camera transformation versus Object transformation

3dlinear-transformationsmatricesrotationsvectors

A 3D camera is located at position $(eye_x,eye_y,eye_z)$ and looking at some object located at position $(0,0,0)$.

How can I achieve the same visual result but rotating the object (and having a static camera) instead of translating the camera around?

For example, if the camera eye is located at position $(2,2,2)$ looking at $(0,0,0)$, I guess I should rotate at least the object around Y axis 45° degrees. However, I don't know what calculations starting from the camera vectors (eye,at) should I apply in order to get there.

camera setup

This is the camera transformation:
camera rotation

This is the desired transformation:
object rotation

Best Answer

Prepare yourself for long and detailed explanation.

Let W be the transformation of the target object and V is the view matrix obtained from the transformation of the camera:

$ W=\begin{bmatrix} mR_x&mR_y&mR_z&0\\ mU_x&mU_y&mU_z&0\\ mL_x&ML_y&mL_z&0\\ mT_x&mT_y&mT_z&1\\ \end{bmatrix} \ \ \ \ , \ \ \ \ \ V=\begin{bmatrix} cR_x&cU_x&cL_x&0\\ cR_y&cU_y&cL_y&0\\ cR_z&cU_z&cL_z&0\\ -(cR\cdot cT)&-(cU\cdot cT)&-(cL\cdot cT)&1\\ \end{bmatrix} $

where

  • mR, mU and mL are the local right, up and look vectors (axis), mT is the translation (at, in your case) vector of the target object;
  • cR, cU and cL are the local right, up and look vectors (axis), cT is the translation (eye, in your case) vector of the camera.

Since the camera always looks at the the object, the following should be used to obtain the cR, cU and cL vectors of the camera:

$ vU = (0, 1, 0)\\ cL = normalize(mT-cT) \\ cR = normalize(vU \times cL) \\ cU=normalize(cL\times cR)$

NOTE: "$ \times$" indicates a cross-product and "$\cdot$" indicates a dot-product.

To get the same image after projection, the multiplication of W (world) and V (view) matrices should remain the same (i.e. $W_0 \times V_0 = W_n \times V_n $). Note that I assumed the projection matrix does not change.


So you have initial world and view matrices, i.e. $W_0$ and $V_0$. Thus you also have $W_0 \times V_0$.

Then you moved the camera to somewhere else (i.e. cT is changed) but the target object is still at the origin. So you need to re-build the V matrix as I explained above. Let's name it as $V_n$.

Thus,

$W_n \times V_n=W_0 \times V_0 \\ \Rightarrow W_n=W_0 \times V_0 \times V_n^{-1}$

where $V_n^{-1}$ is the inverse of $V_n$; and $W_n$ is the new world matrix of the target object to guarantee the same image after projection.

If you extract the local axis vectors from $W_n$ then you can find the rotation angles compared to the initial state:

$ mR_n \cdot mR_0 = |mR_n| \ |mR_0| \ \cos\alpha\\ mU_n \cdot mU_0 = |mU_n| \ |mU_0| \ \cos\beta\\ mL_n \cdot mL_0 = |mL_n| \ |mL_0| \ \cos\theta $

Note that the distance between camera and the target object should be the same if you want to only rotate the target object. Or else you'll also need to re-position it. The updated translation vector can be extracted from $W_n$ as well.