Eigen Rows Versus Cols
TL;DR: The use of a Eigen::Matrix3Xd
or Eigen::Matrix3Xf
should be prefered to store 3D pointclouds in 3D libraries.
In C++, Eigen matrices are one of the most common object used to store the raw information of 3D objects. This is the case for both libIGL and cilantro. However, this two libraries are using two different coordinates to store the information, e.g., in libIGL, vertices would be stored in a N by 3 matrix and Cilantro would store it into a 3 by N matrix. While this question might seems insignificant, we will show why it matter and which one should you use?
It is more logical given the standard Eigen structures
While as shown in the libIGL documentation, the use of a N by 3 matrix seems more readable, it creates few problems. However, the natural structure to store a 3D point would be Eigen::Vector3d
which is actually defined as a Eigen::Matrix <double , 3, 1>
in the background. Therefore, it seems natural to stores points using a Eigen::Matrix <double , 3, Eigen::Dynamic>
.
It is a natural fit for the geometry module
An additional tool build into the Eigen library is the geometry module which allows to apply transformations to a set of 3D points. For instance applying an affine transformations to a 3 by N matrix would be performed as follow:
Eigen::Affine3d transform
Eigen::Matrix3Xd vertices, transformed_vertices;
transformed_vertices = transform * vertices;
While using the format defined in libIGL would be writen like:
Eigen::Affine3d transform
Eigen::MatrixX3d vertices, transformed_vertices;
transformed_vertices = (transform * vertices.transpose() ).transpose();
It is safer
One problem that might occur in constantly using .transpose()
is that the users might:
Eigen::Affine3d transform
Eigen::MatrixXd vertices, transformed_vertices;
vertices = vertices.transpose();
transformed_vertices = transform * vertices;
transformed_vertices = transformed_vertices.transpose();
Which should actually happen through .transposeInPlace()
to avoid an aliasing problem.