The post is similar to Find Closest Plane Between Points In 3D By Levmar Algorithm.
The vtkPlane in vtk9.0.2 or the newer version provides a way to calculate the fitting plane for a few points.
static bool ComputeBestFittingPlane(vtkPoints* pts, double* origin, double* normal);
.
The origin will be the centroid of the points. The normal is determined by using the covariance matrix of the points relative to the centroid.
The following project is based on VTK9.0.2.
cmake_minimum_required(VERSION 2.8)
project(untitled)
add_executable(${PROJECT_NAME} "main.cpp" "point.hpp")
find_package( VTK COMPONENTS vtkCommonCore vtkRenderingCore vtkInteractionStyle RenderingCore
RenderingOpenGL2 FiltersSources)
if (VTK_VERSION VERSION_LESS "8.90.0")
# old system
include(${VTK_USE_FILE})
else ()
# vtk_module_autoinit is needed
vtk_module_autoinit(
TARGETS ${PROJECT_NAME}
MODULES ${VTK_LIBRARIES}
)
endif ()
target_link_libraries( ${PROJECT_NAME} ${VTK_LIBRARIES} )
Code snippet:
#include <iostream>
#include <vector>
#include <iostream>
#include <vtkPolyData.h>
#include <vtkProperty.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkPlane.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkPoints.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include "./point.hpp"
#include <vtkPlane.h>
#include <vtkPlaneSource.h>
#include <vtkTransform.h>
#define vtkSPtr vtkSmartPointer
#define vtkSPtrNew(Var, Type) vtkSPtr<Type> Var = vtkSPtr<Type>::New();
int main() {
std::vector<Point> samplePts{ {-25.1339, -5.76816, -0.995864},
{-14.7021, -2.73063, 18.1714},
{-0.458432, -1.09882, 24.679},
{12.8826, -1.73559, 17.6288},
{23.2548, -4.19458, -1.25975},
{23.2548, -2.19458, 6.25975} };
vtkSPtrNew( samPoints, vtkPoints );
for( auto pt: samplePts )
{
samPoints->InsertNextPoint( pt.point );
}
Point origin, normal;
vtkPlane::ComputeBestFittingPlane( samPoints, origin.point, normal.point );
// =============== draw plane ==============
vtkSPtrNew( plane, vtkPlane );
plane->SetNormal( normal[0], normal[1], normal[2] );
plane->SetOrigin( origin[0], origin[1], origin[2] );
vtkSmartPointer<vtkPlaneSource> planeSource =
vtkSmartPointer<vtkPlaneSource>::New();
planeSource->SetCenter( plane->GetOrigin() );
planeSource->SetNormal( plane->GetNormal() );
planeSource->Update();
vtkSmartPointer<vtkPolyDataMapper> planeMapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
planeMapper->SetInputData( planeSource->GetOutput() );
planeMapper->Update();
int scaleValue = 60;
vtkSmartPointer<vtkActor> planeActor =
vtkSmartPointer<vtkActor>::New();
planeActor->SetMapper( planeMapper );
planeActor->GetProperty()->SetColor( 0, 1, 1 );
planeActor->GetProperty()->SetOpacity( 1 );
Point originPt( plane->GetOrigin() );
vtkSPtrNew( trans, vtkTransform );
trans->Translate( originPt.point );
trans->Scale( scaleValue, scaleValue, scaleValue );
trans->Translate( (-originPt).point );
planeActor->SetUserTransform( trans );
// =============== draw points =============
vtkSPtrNew( polyData, vtkPolyData );
vtkSPtrNew( points, vtkPoints );
vtkSPtrNew( cells, vtkCellArray );
for( int i = 0; i < samplePts.size(); ++i )
{
points->InsertNextPoint( samplePts[i].point );
vtkIdType ids[] = { i };
cells->InsertNextCell( 1, ids );
}
polyData->SetPoints( points );
polyData->SetVerts( cells );
polyData->Modified();
vtkSPtrNew( mapper, vtkPolyDataMapper );
mapper->SetInputData( polyData );
vtkSPtrNew( actor, vtkActor );
actor->SetMapper( mapper );
actor->GetProperty()->SetPointSize( 5 );
vtkSPtrNew( renderer, vtkRenderer );
renderer->AddActor( actor );
renderer->AddActor( planeActor );
renderer->SetBackground( 0, 0, 0 );
vtkSPtrNew( renderWindow, vtkRenderWindow );
renderWindow->AddRenderer( renderer );
vtkSPtrNew( renderWindowInteractor, vtkRenderWindowInteractor );
renderWindowInteractor->SetRenderWindow( renderWindow );
vtkSPtrNew(style, vtkInteractorStyleTrackballCamera);
renderWindowInteractor->SetInteractorStyle(style);
renderer->ResetCamera();
renderWindow->Render();
renderWindowInteractor->Start();
return 0;
}
Result:
The result from Levmar Algorithm:
[…] The file CMakeLists.txt is similar to https://www.weiy.city/2021/12/find-closest-plane-between-points-in-3d-by-covariance-matrix/. […]