Ellipsoid fitting in C++ using Eigen. Widely inspired by https://www.mathworks.com/matlabcentral/fileexchange/24693-ellipsoid-fit
The radii of the fitted ellipsoid surface are arranged based on the smallest rotation angle of the ellipsoid axes, deviated from the defined reference frame, along its axis of rotation containing its approximate center.
This arrangement also applies to the sequence of the eigenvalues and their corresponding eigenvectors. Consequently, the transpose of the eigenvectors' matrix from *evec_column_p
, generated by the function
Parameters ellipsoid::fit(..., Eigen::Vector3d* eval_p, Eigen::Matrix3d* evec_column_p, ...);
can be used as a rotation matrix to rotate the fitted ellipsoid to the nearest non-rotated ellipsoid, in term of rotation angle.
Mathematical Details
From the C++ function above, suppose *eval_p
contains eval_p->asDiagonal()
denoted as evec_column_p->transpose()
be denoted as
Consider the inputs be
Hence, the rotation from
...
Eigen::Vector3d d_in; // Inputs
Eigen::Matrix3d R = evec_column_p->transpose();
// Perform the multiplication d_out = R * d_in
Eigen::Vector3d d_out = R * d_in;
...
Additionally, the transformation from the fitted ellipsoid to a unit sphere can be achieved using
...
Eigen::Vector3d d_in; // Inputs
Eigen::Matrix3d R = evec_column_p->transpose();
Eigen::Matrix3d sqrt_E = eval_p->cwiseSqrt().asDiagonal();
// Perform sphere mapping d_out = E^(0.5) * R * d_in
Eigen::Vector3d d_out = sqrt_E * R * d_in;
...
This process involves first rotating the inputs, followed by scaling them.
If any of the radii results in a 'NaN' value, it indicates that the fitted surface is a hyperboloid, not an ellipsoid.
Possible causes include:
- Incomplete coverage of the surface points in the input data.
- Numerical errors during the least square minimization in the fitting process. (A fix is required in the future)
The ellipsoid-fit package contains the following:
-
Libraries:
- ellipsoid-fit (shared)
-
Examples:
- fitting-example
-
Tests:
- test-ellipsoid-fit
The ellipsoid-fit project is packaged using PID, a build and deployment system based on CMake.
If you wish to adopt PID for your develoment please first follow the installation procedure here.
If you already are a PID user or wish to integrate ellipsoid-fit in your current build system, please read the appropriate section below.
This method is for developers who want to install and access ellipsoid-fit from their PID workspace.
You can use the deploy
command to manually install ellipsoid-fit in the workspace:
cd <path to pid workspace>
pid deploy package=ellipsoid-fit # latest version
# OR
pid deploy package=ellipsoid-fit version=x.y.z # specific version
Alternatively you can simply declare a dependency to ellipsoid-fit in your package's CMakeLists.txt
and let PID handle everything:
PID_Dependency(ellipsoid-fit) # any version
# OR
PID_Dependency(ellipsoid-fit VERSION x.y.z) # any version compatible with x.y.z
If you need more control over your dependency declaration, please look at PID_Dependency documentation.
Once the package dependency has been added, you can use ellipsoid-fit/ellipsoid-fit
as a component dependency.
You can read PID_Component and PID_Component_Dependency documentations for more details.
This method allows to build the package without having to create a PID workspace manually. This method is UNIX only.
All you need to do is to first clone the package locally and then run the installation script:
git clone https://gite.lirmm.fr/rpc/math/ellipsoid-fit.git
cd ellipsoid-fit
./share/install/standalone_install.sh
The package as well as its dependencies will be deployed under binaries/pid-workspace
.
You can pass --help
to the script to list the available options.
There are two ways to integrate ellipsoid-fit in CMake project: the external API or a system install.
The first one doesn't require the installation of files outside of the package itself and so is well suited when used as a Git submodule for example. Please read this page for more information.
The second option is more traditional as it installs the package and its dependencies in a given system folder which can then be retrived using find_package(ellipsoid-fit)
.
You can pass the --install <path>
option to the installation script to perform the installation and then follow these steps to configure your environment, find PID packages and link with their components.
You can pass --pkg-config on
to the installation script to generate the necessary pkg-config files.
Upon completion, the script will tell you how to set the PKG_CONFIG_PATH
environment variable for ellipsoid-fit to be discoverable.
Then, to get the necessary compilation flags run:
pkg-config --static --cflags ellipsoid-fit_ellipsoid-fit
pkg-config --variable=c_standard ellipsoid-fit_ellipsoid-fit
pkg-config --variable=cxx_standard ellipsoid-fit_ellipsoid-fit
To get linker flags run:
pkg-config --static --libs ellipsoid-fit_ellipsoid-fit
With Doxygen installed, the API documentation can be built locally by turning the BUILD_API_DOC
CMake option ON
and running the doc
target, e.g
pid cd ellipsoid-fit
pid -DBUILD_API_DOC=ON doc
The resulting documentation can be accessed by opening <path to ellipsoid-fit>/build/release/share/doc/html/index.html
in a web browser.
The license that applies to the whole package content is GNULGPL. Please look at the license.txt file at the root of this repository for more details.
ellipsoid-fit has been developed by the following authors:
- Benjamin Navarro (LIRMM)
- CK-Explorer ()
Please contact Benjamin Navarro ([email protected]) - LIRMM for more information or questions.