VTK notes - use the vtkSplineFilter class to process 3D space curves

In the previous notes VTK Notes-Graphics-Segment Smoothing-vtkSplineFilter class , I learned that
vtkSplineFilterthe class is used to refine the input data of multi-line segments and output point sets with more line segments;
vtkSplineFilterthe class can not only be used for interpolation, but also for sampling ; The method of interpolation or sampling can be set
through the interface and interface vtkSplineFilterof the class ; the interface sets the number of thinning, which is used to set the number of output line segments;SetSubdivideToSpecified()SetSubdivideToLength()
SetSubdivideToSpecified()SetNumberOfSubdivisions

spline->SetSubdivideToSpecified();
spline->SetNumberOfSubdivisions(3);	

SetSubdivideToLength()The interface sets the length of each line segment; divide the sum of the lengths of the curves by the length of each line segment to get the final number of line segments;

vtkNew<vtkSplineFilter> spline;
spline->SetInputDataObject(polyData);
spline->SetSpline(cardinal_spine);
spline->SetSubdivideToLength();
spline->SetLength(1);

sample code

Use vtkParametricSplinethe class to interpolate four points into a curve;

double p0[3] = {
    
     1.0, 0.0, 0.0 };
double p1[3] = {
    
     0.0, 1.0, 0.0 };
double p2[3] = {
    
     0.0, 0.0, 1.0 };
double p3[3] = {
    
     1.0, 2.0, 3.0 };

vtkNew<vtkPoints> points;
points->InsertNextPoint(p0);
points->InsertNextPoint(p1);
points->InsertNextPoint(p2);
points->InsertNextPoint(p3);

vtkNew<vtkParametricSpline> spline;
spline->SetPoints(points);
	
vtkNew<vtkParametricFunctionSource> functionSource;
functionSource->SetParametricFunction(spline);
functionSource->Update();

vtkNew<vtkPolyDataMapper> splineMapper;
splineMapper->SetInputConnection(functionSource->GetOutputPort());

vtkNew<vtkActor> splineActor;
splineActor->SetMapper(splineMapper);

vtkNew<vtkPolyData> resultPolydata;
resultPolydata->SetPoints(points);

vtkNew<vtkVertexGlyphFilter> resultGlyphFilter;
resultGlyphFilter->AddInputData(resultPolydata);
resultGlyphFilter->Update();

vtkNew<vtkPolyDataMapper> resultMapper;
resultMapper->SetInputConnection(resultGlyphFilter->GetOutputPort());
vtkNew<vtkActor> resultActor;
resultActor->SetMapper(resultMapper);
resultActor->GetProperty()->SetPointSize(5);//定义点的尺寸大小,这样点才能在画布上显示出来
resultActor->GetProperty()->SetColor(1, 0.0, 0.0);
	
vtkNew<vtkRenderer> ren1;
ren1->AddActor(splineActor);
ren1->AddActor(resultActor);
ren1->SetBackground(0.1, 0.2, 0.4);

vtkNew<vtkRenderWindow> renWin;
renWin->AddRenderer(ren1);
renWin->SetSize(300, 300);

vtkNew<vtkRenderWindowInteractor> iren;
iren->SetRenderWindow(renWin);
iren->Initialize();
iren->Start();

insert image description here
Or use vtkSplineFiltera class to interpolate four points into a curve;

double p0[3] = {
    
     1.0, 0.0, 0.0 };
double p1[3] = {
    
     0.0, 1.0, 0.0 };
double p2[3] = {
    
     0.0, 0.0, 1.0 };
double p3[3] = {
    
     1.0, 2.0, 3.0 };

vtkNew<vtkPoints> points;
points->InsertNextPoint(p0);
points->InsertNextPoint(p1);
points->InsertNextPoint(p2);
points->InsertNextPoint(p3);

vtkNew<vtkCellArray> lines;
lines->InsertNextCell(4);
for (unsigned long i = 0; i < 4; ++i) {
    
    
	lines->InsertCellPoint(i);
}
vtkNew<vtkPolyData> polyData;
polyData->SetPoints(points);
polyData->SetLines(lines);

vtkNew<vtkSplineFilter> spline;
vtkNew<vtkCardinalSpline> cardinal_spine;

spline->SetInputDataObject(polyData);
spline->SetSpline(cardinal_spine);
spline->SetSubdivideToLength();
spline->SetLength(0.1);
spline->Update();

vtkNew<vtkPolyDataMapper> splineMapper;
splineMapper->SetInputConnection(spline->GetOutputPort());

vtkNew<vtkActor> splineActor;
splineActor->SetMapper(splineMapper);

vtkNew<vtkPolyData> resultPolydata;
resultPolydata->SetPoints(points);

vtkNew<vtkVertexGlyphFilter> resultGlyphFilter;
resultGlyphFilter->AddInputData(resultPolydata);
resultGlyphFilter->Update();

vtkNew<vtkPolyDataMapper> resultMapper;
resultMapper->SetInputConnection(resultGlyphFilter->GetOutputPort());
vtkNew<vtkActor> resultActor;
resultActor->SetMapper(resultMapper);
resultActor->GetProperty()->SetPointSize(5);//定义点的尺寸大小,这样点才能在画布上显示出来
resultActor->GetProperty()->SetColor(1, 0.0, 0.0);
	
vtkNew<vtkRenderer> ren1;
ren1->AddActor(splineActor);
ren1->AddActor(resultActor);
ren1->SetBackground(0.1, 0.2, 0.4);

vtkNew<vtkRenderWindow> renWin;
renWin->AddRenderer(ren1);
renWin->SetSize(300, 300);

vtkNew<vtkRenderWindowInteractor> iren;
iren->SetRenderWindow(renWin);
iren->Initialize();
iren->Start();
return 0;

insert image description here
SetLength(1)The result of use :
insert image description here
Note: From the above figure, it can be seen that vtkSplineFilterthe class sampling point and the line segment after interpolation do not necessarily pass through the position of the input point; when the number is
set to 3;SetNumberOfSubdivisions

double p0[3] = {
    
     1.0, 0.0, 0.0 };
double p1[3] = {
    
     0.0, 1.0, 0.0 };
double p2[3] = {
    
     0.0, 0.0, 1.0 };
double p3[3] = {
    
     1.0, 2.0, 3.0 };

vtkNew<vtkPoints> points;
points->InsertNextPoint(p0);
points->InsertNextPoint(p1);
points->InsertNextPoint(p2);
points->InsertNextPoint(p3);
vtkNew<vtkCellArray> lines;
lines->InsertNextCell(4);
for (unsigned long i = 0; i < 4; ++i) {
    
    
	lines->InsertCellPoint(i);
}
vtkNew<vtkPolyData> polyData;
polyData->SetPoints(points);
polyData->SetLines(lines);

vtkNew<vtkSplineFilter> spline;
vtkNew<vtkCardinalSpline> cardinal_spine;

spline->SetInputDataObject(polyData);
spline->SetSpline(cardinal_spine);
spline->SetSubdivideToSpecified();
spline->SetNumberOfSubdivisions(3);	
spline->Update();

vtkNew<vtkPolyDataMapper> splineMapper;
splineMapper->SetInputConnection(spline->GetOutputPort());

vtkNew<vtkActor> splineActor;
splineActor->SetMapper(splineMapper);

vtkNew<vtkPolyData> resultPolydata;
resultPolydata->SetPoints(points);

vtkNew<vtkVertexGlyphFilter> resultGlyphFilter;
resultGlyphFilter->AddInputData(resultPolydata);
resultGlyphFilter->Update();

vtkNew<vtkPolyDataMapper> resultMapper;
resultMapper->SetInputConnection(resultGlyphFilter->GetOutputPort());
vtkNew<vtkActor> resultActor;
resultActor->SetMapper(resultMapper);
resultActor->GetProperty()->SetPointSize(5);//定义点的尺寸大小,这样点才能在画布上显示出来
resultActor->GetProperty()->SetColor(1, 0.0, 0.0);

vtkNew<vtkRenderer> ren1;
ren1->AddActor(splineActor);
ren1->AddActor(resultActor);
ren1->SetBackground(0.1, 0.2, 0.4);

vtkNew<vtkRenderWindow> renWin;
renWin->AddRenderer(ren1);
renWin->SetSize(300, 300);

vtkNew<vtkRenderWindowInteractor> iren;
iren->SetRenderWindow(renWin);
iren->Initialize();
iren->Start();
return 0;

insert image description here
SetNumberOfSubdivisionsWhen the set number is 30;
insert image description here

Further processing of curve data

If our input data is a curve with a lot of interference, and there are many high-frequency signals on the curve; for example, in the figure below,
insert image description here
we can first perform a sampling operation on the data (in fact, low-pass filtering should be performed here) , and then interpolation operation, you will get a slightly smoother curve;
vtkSplineFilterthe class can achieve such a simple operation;
when we move or modify the position of a certain point on a smooth curve, it may destroy the smoothness of the curve. You can use vtkSplineFilterclasses to repair smoothness, but using vtkSplineFilterclasses is not the best solution. The filtering of 3D curves should be a better choice.

Guess you like

Origin blog.csdn.net/liushao1031177/article/details/120966778