How to find out the rotation matrix for the oriented bounding box

1.9k views Asked by At

So I am using the Matterport 3D dataset for my task and it has described the oriented bounding box using the standard structure with one change as follows:

"obb": {
        "centroid":[3.39208,-1.72134,1.13262],
        "axesLengths":[1.11588,0.619098,0.439177],
        "dominantNormal":[-0.707107,-0.707107,0],
        "normalizedAxes":[0,0,1,-0.707107,0.707107,0,-0.707107,-0.707107,0]
      }

I understand that the oriented bounding box is typically defined by the centroid, local coordinate system axes, and lengths along those axes.

In my case, considering that the object is only rotated around the vertical axis (z-axis) in world coordinate frame, I want to find out the angle by which it is rotated around the z-axis. But for that, I need the rotation matrix which transforms the world coordinate system into the local coordinate system. In standard representation case, the rotation matrix is the just 3x3 matrix with the axes as column vectors. However, in this case, if you look at the normalized axes array there are 9 values given with no convention as to which axis should be the first column vector or second column vector in rotation matrix.

With the assumption that, the object position is vertical and rotated only around the z-axis, I can determine the last column of the rotation matrix. For example, [0, 0, 1] in the aforementioned example. But how to determine the other two axes? Is there a way to take "dominantNormal" information into consideration in determining that?

2

There are 2 answers

0
bhushan On BEST ANSWER

Let us take the example given in the problem. Normalized axes are given but not in any particular order as follows.

"normalizedAxes":[0,0,1,-0.707107,0.707107,0,-0.707107,-0.707107,0]

Since we know that, the object is rotated only around the z-axis, the third column in the rotation matrix would be [0, 0, 1]. So that leaves us with two columns; let us call them axis_0, axis_1.

So,

axis_0 = [-0.707107, 0.707107, 0] 
axis_1 = [-0.707107, -0.707107, 0]

You can calculate the angle that each of this axis makes with the x-axis in the global coordinate system using the inverse tangent function. Let us say, the angle made by the axis_0 and axis_1 are angle_0 and angle_1 respectively.

Either of the following relation has to be true as we know that axis_0 and axis_1 are orthogonal.

angle_0 = angle_1 + 90 or angle_1 = angle_0 + 90

So with the aforementioned example, you can notice that,

angle_0 = 135 degrees
angle_1 = 225 degrees (-135 degrees)

As we consider the counterclockwise rotation as positive, the axis which makes the smaller angle would be the first column in the rotation matrix and the other axis would be the second column in the rotation matrix.

The rotation matrix, in this case, looks like the following:

[ [ -0.707107, -0.707107,  0],
  [ 0.707107,  -0.707107,  0],
  [ 0,          0,         1],
]

If you use arctan2 function, be careful handling the special cases in which the axes are rotated clockwise and rotated y-axis and x-axis lie in the first and fourth quadrant respectively.

4
meowgoesthedog On

Assuming that the normalizeAxes property has the following meaning:

[X1, X2, X3, Y1, Y2, Y3, Z1, Z2, Z3]

Then the local-to-world rotation matrix's columns are equal to the vectors XYZ:

    | X1 Y1 Z1 |
R = | X2 Y2 Z2 |
    | X3 Y3 Z3 |

The world-to-local rotation matrix is of course just the inverse (= transpose) of this:

         | X1 X2 X3 |
inv(R) = | Y1 Y2 Y3 |
         | Z1 Z2 Z3 |

Taking the translation centroid = [C1, C2, C3] into consideration:

    | X1 Y1 Z1 C1 |
T = | X2 Y2 Z2 C2 |
    | X3 Y3 Z3 C3 |
    | 0  0  0  1  |

         | X1 X2 X3 -dot(C, X) |
inv(T) = | Y1 Y2 Y3 -dot(C, Y) |
         | Z1 Z2 Z3 -dot(C, Z) |
         | 0  0  0       1     |

Not sure what dominantNormal represents (there doesn't seem to be any openly available documentation for it); might be metadata for shading, or a measure of the geometry distribution within this OBB.