Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pointing the camera at O(0,0,0), 45 deg

I am having problems setting the camera such that it points at the origin O(0,0,0) with a degree of 45° to all other axes with all coordinates positive (which should have the same value, of course). You can see in the image the closest I've got

enter image description here

However, as you can see, the x value is negative here, so the camera is on the wrong side of the YZ plane.

The complete compilable project can be found at this revision in a gist.

The relevant matrix multiplications done are

osg::Matrixd rotate_x(
        1.0, 0.0, 0.0, 0.0,
        0.0, q_cos, -q_sin, 0.0,
        0.0, q_sin, q_cos, 0.0,
        0.0, 0.0, 0.0, 1.0 
);
osg::Matrixd rotate_y(
        q_cos, 0.0, q_sin, 0.0,
        0.0, 1.0, 0.0, 0.0,
        -q_sin, 0.0, q_cos, 0.0,
        0.0, 0.0, 0.0, 1.0 
);
camera_pos = camera_pos * rotate_x;
camera_pos = camera_pos * rotate_y;

in the file Simple.cpp.

I'm trying to figure out how this works (both mathematically and programmatically). I would prefer solutions which rely as little as possible on openscenegraph, and more on the math side, as I'd like to do the maths myself at first, to get a real grasp of how it works. So no quaternions or other advanced stuff yet, which are not taught in a basic linear algebra university course.

like image 265
Flavius Avatar asked Nov 13 '22 01:11

Flavius


1 Answers

Your rotate_y matrix looks flipped to me.

Starting with rotation matrix from glRotate, I simplified the resulting matrix with xyz = (0,1,0), and I got this (in column major order (standard opengl notation)

 q_cos  0  q_sin   0 
 0      1  0       0 
-q_sin  0  q_cos   0
 0      0  0       1

However, you're supplying the same matrix in row major order:

osg::Matrixd rotate_y(
        q_cos,  0.0, q_sin,  0.0,
        0.0,    1.0, 0.0,    0.0,
        -q_sin, 0.0, q_cos,  0.0,
        0.0,    0.0, 0.0,    1.0
);

-q_sin should be element [2] of the matrix, and q_sin should be element [8], but it looks like you've flipped them.


EDIT

OpenGL and OSG typically represent matrices in column major format, when you see a 4x4 matrix, it is laid out like the following

[0]    [4]     [8]     [12]
[1]    [5]     [9]     [13]
[2]    [6]     [10]    [14]
[3]    [7]     [11]    [15]

Where [0] is the first element of the array, 1 is the second, etc.

When you create a matrix with OSG, you're defining 16 sequential memory elements, from [0] to [15]

osg::Matrixd rotate_y([0], [1], [2]......,[15]);

When you break up the command into 4 rows, it looks like this:

osg::Matrixd rotate_y(
   [0], [1], [2], [3],
   [4], [5], [6], [7],
   [8], [9], [10],[11],
   [12],[13],[14],[15] 
)

Do you see how this is transposed from the original column vector representation? You need to flip it because the 4x4 matrix examples you find are the internet are represented by column vectors, while you're currently uploading them as row vectors. It doesn't mean that what you're reading is 'wrong', it's just in a different representation.

like image 182
Tim Avatar answered Dec 15 '22 13:12

Tim