I found a new way to make interpolation spline curve smoother. Let’s explore it based on the previous post, VTK – Make Interpolation Spline Curve Smoother.
Take every point and its neighbor points on the curve, generate two vectors and . Make the second point B to be the midpoint of the two neighbors if the angle between vectors and .
#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>
#include <vtkParametricSpline.h>
#define vtkSPtr vtkSmartPointer
#define vtkSPtrNew(Var, Type) vtkSPtr<Type> Var = vtkSPtr<Type>::New();
int main() {
std::vector<Point> samplePts{ {27.9388, 0.907182, -20.4173},
{28.0513, -0.277626, -13.3988},
{27.0475, -1.27512, -7.81182},
{22.7821, -2.62784, -1.08624},
{22.4706, -2.9135, 0.506759},
{21.9129, -3.76875, 5.38579},
{19.7999, -4.21017, 7.3692},
{19.3283, -4.92608, 11.4519},
{18.8287, -5.68737, 15.794},
{16.3817, -6.29968, 18.6871},
{12.7998, -6.67389, 19.8438},
{9.46368, -7.40502, 23.1769},
{6.60901, -7.70747, 24.1236},
{0.370036, -8.26548, 25.5853},
{-1.09791, -8.06504, 23.9734},
{-7.87406, -8.22193, 22.9127},
{-11.0107, -8.50105, 23.6392},
{-13.5609, -7.96833, 19.7511},
{-9.93712, -7.00742, 15.1475},
{-13.0518, -6.88037, 13.4857},
{-18.2671, -6.69763, 10.88},
{-20.0041, -6.08959, 6.78607},
{-21.1299, -5.80015, 4.74973},
{-22.5146, -5.0249, -0.226881},
{-22.3064, -4.72078, -1.95894},
{-26.8748, -3.7558, -8.9871},
{-27.835, -3.04119, -13.4817},
{-29.3375, -1.80509, -21.21} };
// =============== draw spline =====================
vtkSPtrNew( samplePoints, vtkPoints );
for( int i = 0; i < samplePts.size(); ++i )
{
samplePoints->InsertNextPoint( samplePts[i].point );
}
vtkSPtrNew(spline1, vtkParametricSpline);
spline1->SetPoints(samplePoints);
double u = 1.0 / 100;
double dTemp[3] = {0}, outPt[3] = {0};
vtkSPtrNew( splintPts, vtkPoints );
int index = 0;
for (double x = 0; x < 1; x = x + u)
{
dTemp[0] = x;
spline1->Evaluate(dTemp, outPt, nullptr);
if( index % 10 == 0 )
{
splintPts->InsertNextPoint( outPt );
}
index++;
}
splintPts->InsertNextPoint( outPt );
//--------------- change midpoint ----------------
for( int i = 1; i < splintPts->GetNumberOfPoints() - 1; ++i )
{
Point lastPt( splintPts->GetPoint( i-1 ) );
Point pt( splintPts->GetPoint( i ) );
Point nextPt( splintPts->GetPoint( i+1 ) );
Point vec1 = pt - lastPt;
Point vec2 = nextPt - pt;
auto degree = vtkMath::DegreesFromRadians( vtkMath::AngleBetweenVectors( vec1.point, vec2.point ) );
if( degree > 45 )
{
pt = (lastPt + nextPt)/2;
splintPts->SetPoint( i, pt.point );
}
}
// -----------------------------------------------
vtkSPtrNew(spline2, vtkParametricSpline);
spline2->SetPoints( splintPts );
vtkSPtrNew( splintPts2, vtkPoints );
for( double x = 0; x < 1; x = x + u )
{
dTemp[0] = x;
spline2->Evaluate(dTemp, outPt, nullptr);
splintPts2->InsertNextPoint( outPt );
}
vtkSPtrNew( polyData, vtkPolyData );
vtkSPtrNew( points, vtkPoints );
vtkSPtrNew( cells, vtkCellArray );
for( int i = 0; i < splintPts2->GetNumberOfPoints(); ++i )
{
points->InsertNextPoint( splintPts2->GetPoint( i ) );
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( 2 );
vtkSPtrNew( renderer, vtkRenderer );
renderer->AddActor( actor );
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;
}