I want to extract the three first values of a Vector4 type in Eigen, into a Vector3 type. So far I am doing it in a for-loop. Is there a smarter way to do it?
The .head()
member function returns the first n elements of a vector. If n is a compile-time constant, then you can use the templated variant (as in the code example below) and the Eigen library will automatically unroll the loop.
Eigen::Vector4f vec4;
// initialize vec4
Eigen::Vector3f vec3 = vec4.head<3>();
In the Eigen documentation, see Block operations for an introduction to similar operations for extracting parts of vectors and matrices, and DenseBase::head() for the specific function.
The answer of @Jitse Niesen is correct. Maybe this should be a comment on the original question, but I found this question because I had some confusion about Eigen. In case the original questioner, or some future reader has the same confusion, I wanted to provide some additional explanation.
If the goal is to transform 3d (“position”) vectors by a 4x4 homogeneous transformation matrix, as is common in 3d graphics (e.g. OpenGL etc), then Eigen provides a cleaner way to do that with its Transform template class, often represented as the concrete classes Affine3f or Affine3d (as tersely described here). So while you can write such a transform like this:
Eigen::Matrix4f transform; // your 4x4 homogeneous transformation
Eigen::Vector3f input; // your input
Eigen::Vector4f input_temp;
input_temp << input, 1; // input padded with w=1 for 4d homogeneous space
Eigen::Vector4f output_temp = transform * input_temp;
Eigen::Vector3f output = output_temp.head<3>() / output_temp.w(); // output in 3d
You can more concisely write it like this:
Eigen::Affine3f transform; // your 4x4 homogeneous transformation
Eigen::Vector3f input; // your input
Eigen::Vector3f output = transform * input;
That is: an Eigen::Affine3f is a 4x4 homogeneous transformation that maps from 3d to 3d.
Eigen::Vector4f output_temp = transform * input.homogenous();
. You still need one extra line / temporary though - but personally, I prefer to see an explicit division by w
in the code. –
Capacious Yeah, because you know the size is static (3 elements) you should unroll the loop and copy them explicitly. This optimization might be performed by the compiler already, but it can't hurt to do it yourself just in case.
vec4.head<3>()
explicitly unrolls the loop for you using meta programming techniques. –
Olga © 2022 - 2024 — McMap. All rights reserved.