We can use vtkImplicitPolyDataDistance to calculate the distance from a point to the target polydata. It’s better than calculating the distance by iterating to the search point.

The following example puts a sphere that radius is 1 and origin is (0, 0, 0) in the renderer. Our test point is (1.5, 0, 0), so the ideal distance is 0.5, but the resolution of the sphere can bring impact to the final result.

#include <vtkVersion.h>
#include <vtkImplicitPolyDataDistance.h>


#include <vtkActor.h>
#include <vtkFloatArray.h>
#include <vtkPointData.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkVertexGlyphFilter.h>
#include <vtkLineSource.h>

#include "../share/tool.h"

int main(int, char *[])
{
    vtkSmartPointer<vtkSphereSource> sphereSource =
    vtkSmartPointer<vtkSphereSource>::New();
    sphereSource->SetCenter(0.0, 0.0, 0.0);
    sphereSource->SetRadius(1.0f);
    sphereSource->Update();

    vtkSmartPointer<vtkPolyDataMapper> sphereMapper =
    vtkSmartPointer<vtkPolyDataMapper>::New();
    sphereMapper->SetInputConnection( sphereSource->GetOutputPort() );
    sphereMapper->ScalarVisibilityOff();

    vtkSmartPointer<vtkActor> sphereActor =
    vtkSmartPointer<vtkActor>::New();

    sphereActor->SetMapper( sphereMapper );
    sphereActor->GetProperty()->SetOpacity(.3);
    sphereActor->GetProperty()->SetColor(1,0,0);

    vtkSmartPointer<vtkImplicitPolyDataDistance> implicitPolyDataDistance =
    vtkSmartPointer<vtkImplicitPolyDataDistance>::New();
    implicitPolyDataDistance->SetInput(sphereSource->GetOutput());

    PointStruct pt0( 1.5, 0, 0 ), closetPoint;
    double signedDistance = implicitPolyDataDistance->EvaluateFunctionAndGetClosestPoint( pt0.point,
                                                                                        closetPoint.point );
    vtkSmartPointer<vtkLineSource> lineSource = vtkSmartPointer<vtkLineSource>::New();
    lineSource->SetPoint1( pt0.point );
    lineSource->SetPoint2( closetPoint.point );
    lineSource->Update();
    vtkSmartPointer<vtkPolyDataMapper> lineMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    lineMapper->SetInputData( lineSource->GetOutput() );
    vtkSmartPointer<vtkActor> lineActor = vtkSmartPointer<vtkActor>::New();
    lineActor->SetMapper( lineMapper );

    cout << "signedDistance: " << signedDistance << endl;
    cout << "closetPoint: " << closetPoint;

    // ========= compare with test result =========
    vtkPolyData *sPd = sphereSource->GetOutput();
    double absDis = VTK_DOUBLE_MAX;
    for( int i = 0; i < sPd->GetNumberOfPoints(); ++i )
    {
      PointStruct pt( sPd->GetPoint( i ) );
      PointStruct vec = pt - pt0;
      if( absDis > vec.Length() )
      {
          absDis = vec.Length();
      }
    }
    cout << "absDis: " << absDis << endl;
    // ======== finish: compare ==========

    vtkSmartPointer<vtkRenderer> renderer =
    vtkSmartPointer<vtkRenderer>::New();
    renderer->AddViewProp(sphereActor);
    renderer->AddActor( lineActor );

    vtkSmartPointer<vtkRenderWindow> renderWindow =
    vtkSmartPointer<vtkRenderWindow>::New();
    renderWindow->AddRenderer( renderer );

    vtkSmartPointer<vtkRenderWindowInteractor> renWinInteractor =
    vtkSmartPointer<vtkRenderWindowInteractor>::New();
    renWinInteractor->SetRenderWindow( renderWindow );

    renderWindow->Render();
    renWinInteractor->Start();
    return EXIT_SUCCESS;
}

Output:

signedDistance: 0.525072
closetPoint: PointStruct [0.974928, 0, 0]
absDis: 0.570277

If the input data for vtkImplicitPolyDataDistance object is a curve, we can compute every distance from the target point to the point on the curve and choose the minimum one as the final distance.

Categories: VTK

0 0 votes
Article Rating
Subscribe
Notify of
guest

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
trackback

[…] to calculate the distance from a point to the target points set in the post Calculate Distance From A Point To PolyData In VTK. We will try a new way using KD-Tree to find the closest point to the test point. The following […]

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

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