The article shows a way to calculate the length between two points on a curve. We create a ring and put axis actor in the center to show the ring’s orientation and size. Here are implementation details, the data file curve.vtp can be downloaded from my github repository documents. ``````#define vtkSPtr vtkSmartPointer
#define vtkSPtrNew(Var, Type) vtkSPtr<Type> Var = vtkSPtr<Type>::New();

using namespace std;

int main()
{

vtkSPtrNew( mapper, vtkPolyDataMapper );
mapper->SetScalarModeToUsePointData();

vtkSPtrNew( actor, vtkActor );
actor->SetMapper( mapper );
actor->GetProperty()->SetLineWidth( 3 );

vtkSPtrNew( axesActor, vtkAxesActor );

vtkSPtrNew( renderer, vtkRenderer );
renderer->SetBackground( 0, 0, 0 );

vtkSPtrNew( renderWindow, vtkRenderWindow );

vtkSPtrNew( renderWindowInteractor, vtkRenderWindowInteractor );
renderWindowInteractor->SetRenderWindow( renderWindow );

renderer->ResetCamera();
renderWindow->Render();
renderWindowInteractor->Start();
return 0;
}
``````

Now we want to calculate the red part’s length, the calculus thought can help us to get it. Stpe 1, find the points which are closest to the end parts of red line and on the curve. Step 2, collect all points on the curve which are between the closest points. Step 3, compute distance for every two neighboring points and add them up. The algorithm works in the following function.

``````double CalculateDisOnCurve(vtkPolyData *polydata, const PointStruct &pt0, const PointStruct &pt1)
{
vtkSPtrNew( cellLocator, vtkCellLocator );
cellLocator->SetDataSet( polydata );
cellLocator->BuildLocator();

PointStruct closetPt;
vtkIdType cellId;
int subId;
double dist2;
vtkSPtrNew( cell, vtkGenericCell );
cellLocator->FindClosestPoint( (double *)pt0.point, closetPt.point, cell, cellId, subId, dist2 );
cellLocator->FindClosestPoint( (double *)pt1.point, closetPt.point, cell, cellId, subId, dist2 );
vtkIdType closetPtIds = { -1, -1 };
for( int i = 0; i < polydata->GetNumberOfPoints(); ++i )
{
PointStruct pt( polydata->GetPoint( i ) );
if( pt == closetPt )
{
closetPtIds = i;
}
else if( pt == closetPt )
{
closetPtIds = i;
}
}
if( -1 == closetPtIds || -1 == closetPtIds )
{
return -1;
}
// We can be sure closetPtIds < closetPtIds in our widget polydata.
double lengthOnCurve = 0;
for( vtkIdType i = closetPtIds; i < closetPtIds; ++i )
{
PointStruct p1( polydata->GetPoint( i ) );
PointStruct p2( polydata->GetPoint( i + 1 ) );
lengthOnCurve += (p2-p1).Length();
}
return lengthOnCurve;
}
``````

Use it in the program:

``````    PointStruct p0( 1, 0, 0 ), p1( 0, 1, 0 );

cout << "CalculateDisOnCurve for (1, 0, 0) and (0, 1, 0): "
<< CalculateDisOnCurve( reader->GetOutput(), p0, p1 );
``````

Output:

``````CalculateDisOnCurve for (1, 0, 0) and (0, 1, 0): 1.5713815
``````

``````#include <iostream>
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkActor.h>
#include <vtkConeSource.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkPolyDataMapper.h>
#include <vtkLineSource.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkAxesActor.h>
#include <vtkProperty.h>
#include <vtkCharArray.h>
#include <vtkPointData.h>
#include <vtkCellData.h>
#include <vtkColorTransferFunction.h>
#include <vtkCellLocator.h>
#include <vtkGenericCell.h>

#include "../share/tool.h"
``````
Categories: MathVTK

Article Rating
Subscribe
Notify of 