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 \overrightarrow{AB} and \overrightarrow{BC}. Make the second point B to be the midpoint of the two neighbors if the angle between vectors \overrightarrow{AB} and \overrightarrow{BC}.

#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;
}

Categories: VTK

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments

Content Summary
: Input your strings, the tool can get a brief summary of the content for you.

X
0
Would love your thoughts, please comment.x
()
x