3
$\begingroup$

I want to calculate the orientation (quaternion) of the virtual 3d camera that is looking at some point in 3d space.

The illustration: enter image description here

According to this explanation the quaternion be calculated from axis-angle:

qx = axis.x * sin(angle/2)
qy = axis.y * sin(angle/2)
qz = axis.z * sin(angle/2)
qw = cos(angle/2)

I calculate the axis angle this way (it's a pseudo code):

Point3D axis = normalize(target.position - camera.position); //direction
angle = 0;

But of course the quaternion will be [0, 0, 0, 1] for any given target.position and camera.position (sin(0) = 0). Which is wrong.

I guess that axis-angle to quaternion formula is ok.

Then maybe the axis angle should be calculated differently?

I thought about axis-angle as "the direction in which the object is pointing + the angle around that direction". Maybe it's more like "rotate the object around given direction by this angle"? But if so, axis-angle would not cover all possible 3d orientations.

How to calculate the axis angle having target.position and camera.position?

I work on left-handed coordinate system, but the solution should be quite analogical for right-handed one.


Edit, clarification based on @anon request:

I'm not a mathematician (more a programmer) and some parts of quaternion math looks complicated to me. But I will try to explain what I've meant by "orientation of the camera".

In almost any 3d software (e.g. 3ds max, Blender) or game engine (e.g. Unity) you have two main components for each object: position (x,y,z) and orientation (quaternion x,y,z,w). To get the object in right place you rotate it first by orientation and then translate by position to place in the 3d scene before rendering.

By orientation of camera I mean that, common for 3d software, "object orientation" (on the illustration you can see that camera is rotated and translated from the center of the scene). Precisely speaking, in left-handed coordinate system, with y axis pointing "up".

Let's assume we remove the camera's target from an image for a moment. I should be able to restore the camera by: placing un-rotated camera object in [0,0,0], rotating it by my orientation (which I want to calculate) and then translating by position (which I already have).

$\endgroup$
7
  • 1
    $\begingroup$ Given a pure imaginary quaternion ${\bf x}=a{\bf i}+b{\bf j}+c{\bf k}$, to rotate it around axis $\bf u$ (a unit vector, also a pure imaginary quaternion) by angle $2\theta$ (according to right-hand rule), one sets ${\bf q}=\cos\theta+{\bf u}\sin\theta$ and then computes ${\bf q xq}^{-1}$ with quaternion multiplication. I don't know why you think quaternions can't cover all possible 3D orientations - not only do they cover them all, but they double cover them all! I am having trouble understanding what your question is. Can you make it more mathematical? $\endgroup$
    – anon
    Commented Sep 20, 2015 at 17:15
  • $\begingroup$ I have not said that "quaternions can't cover all possible 3D orientations", I'm sure they do, double time. I said that the second interpretation of axis-angle that I've presented does not cover it. And the first one gives me the paradox of [0, 0, 0, 1] quaternion ("not rotated") for any given target and camera position (which is wrong). So either first or second formula must be wrong. Maybe I miss something in the concept of axis-angle. $\endgroup$
    – PolGraphic
    Commented Sep 20, 2015 at 17:19
  • 1
    $\begingroup$ Well, a rotation is not the same thing as (what you call an) orientation. Rotations go from one orientation to another, and there is no canonical choice of "original" orientation for all objects. Also, if your camera is the origin in space, then applying a rotation will not only change the object's orientation in space but also its position - is that what you want? $\endgroup$
    – anon
    Commented Sep 20, 2015 at 17:21
  • $\begingroup$ So the axis-angle is the rotation and not the orientation? Or I just calculated the rotation and not the axis-angle at all? I apply the transformation in order that prevents problems with position (rotate the object then transform). I have the position of camera, I have the position of target. I want to calculate the orientation of camera (as quaternion) - calculate (extract), not apply (I need it for further calculations). $\endgroup$
    – PolGraphic
    Commented Sep 20, 2015 at 17:24
  • 1
    $\begingroup$ What does "orientation of camera (as quaternion)" mean? I know that quaternions describe 3D rotations. Can you say how quaternions are used to describe orientation? Do you pick an original orientation, and then use the quaternion that describes the rotation from the original orientation to the current orientation? If so, then (a) what does the target object have anything to do with the camera's orientation and (b) how can you describe the camera's orientation if all you know is its position and which direction it's facing? That's not enough information to determine its orientation. $\endgroup$
    – anon
    Commented Sep 20, 2015 at 17:28

2 Answers 2

1
$\begingroup$

You did not describe what the "original" orientation of the camera actually is, that is, what the unrotated camera looks like. I'll suppose that the camera would be pointing along the positive $x$-axis and that a vector from the center to the "top" of the camera would point in the direction of the positive $z$-axis.

Now let's say you want the camera pointing downward at a $45$-degree angle in the $x,z$ plane, that is, the axis of the camera will be in the direction of the vector $\left[\frac{\sqrt2}{2}, 0, -\frac{\sqrt2}{2}\right]$, and that the direction to the "top" of the camera will also still be in the $x,z$, plane, in the direction $\left[\frac{\sqrt2}{2}, 0, \frac{\sqrt2}{2}\right]$.

You get the camera into this orientation by rotating it $45$ degrees ($\pi/4$ radians) around the $y$-axis, that is, using the rotation quaternion $\left[0, \sin\left(\frac\pi8\right), 0, \cos\left(\frac\pi8\right)\right]$ (or maybe that should be $-\sin\left(\frac\pi8\right)$ instead of $\sin\left(\frac\pi8\right)$; it depends on which way is a "positive" rotation around the axis).

In short, the axis of rotation that turns your camera to the desired orientation is usually nowhere near the axis along which the camera ends up pointing.

The axis and angle to achieve a general orientation is not usually as obvious as in this simple case. Rather than trying to guess it directly, you are probably better off performing a series of simple rotations, for example elevate or depress the angle of the camera and then rotate it around the vertical axis (the $z$ axis in my example, or whichever of the axes is vertical in your system). If you also want the camera to be "twisted" around its own axis, then you might want to rotate it about that axis before the other two rotations.

To represent a sequence of rotations, you multiply together the quaternions for each rotation. You then have a single quaternion that represents a single rotation taking the camera from its original orientation to the desired orientation.

$\endgroup$
0
$\begingroup$

The orientation quaternion of the camera describes the rotation needed to make the camera have a new orientation relative to some other orientation.

This other, original orientation is usually some reference orientation: for instance, camera pointing upward the z-direction, camera right along the x-direction, and camera down along the y-direction.

You haven't fully specified the orientation desired of the camera. For instance, once the camera points to the target object, you could spin the camera along that axis and that would be equally valid.

Nevertheless, the angle you need to use for your quaternion is not 0--rather, it should at least be the angle between the reference direction of the camera and the line between the camera and the target.

Edit: moreover, the axis about which you would rotate the camera to point toward the target is not the direction from the camera to the target. Rather, it should be the direction that is perpendicular to that line as well as perpendicular to the current direction of the camera (that is, you want to rotate in the plane of the camera direction and the target's direction). This is accomplished by using the cross product, for example.

$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .