VTK笔记——寻找最近点(vtkCellLocator)在Mesh上找最近点

原文链接https://blog.csdn.net/minmindianzi/article/details/103474941

当你看到找最近点时,可能会立刻想到在一堆点中,通过距离找出最近的点,没错,这是一种寻找最近点的需求。今天我们要说的是另一种寻找最近点的需求,就是在Mesh上找最近点,这个点不一定是Mesh的顶点。
多边形网格是由很多个小的单元组成,类似于这样:
VTK笔记——寻找最近点(vtkCellLocator)在Mesh上找最近点_第1张图片
我们拿其中一个单元格cell来简化模型,
空间中有一个点p,p到cell的最近点要怎么求得?
如果我们把cell想象成一个平面,那就变成了,p到平面ABCD的投影,也是从p点做垂线,求垂线与平面的交点。
没错,这就是vtkCellLocator的基本思想。
VTK笔记——寻找最近点(vtkCellLocator)在Mesh上找最近点_第2张图片

vtkCellLocator
vtkCellLocator本身是一个octree。典型的用法就是求最近的单元或者点。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

int main(int, char *[])
{
  auto sphereSource = vtkSmartPointer<vtkSphereSource>::New();
  sphereSource->Update();
  
  // Create the tree
  auto cellLocator = vtkSmartPointer<vtkCellLocator>::New();
  cellLocator->SetDataSet(sphereSource->GetOutput());
  cellLocator->BuildLocator();
  
  double testPoint[3] = {0.6, 0.5, 0.0};
  
  //Find the closest points to TestPoint
  auto assistCell = vtkSmartPointer<vtkGenericCell>::New();
  double closestPoint[3];//the coordinates of the closest point will be returned here
  double closestPointDist2; //the squared distance to the closest point will be returned here
  vtkIdType cellId; //the cell id of the cell containing the closest point will be returned here
  int subId;
  cellLocator->FindClosestPoint(testPoint, closestPoint, assistCell, cellId, subId, closestPointDist2);
  
  std::cout << "Coordinates of closest point: " << closestPoint[0] << " " << closestPoint[1] << " " << closestPoint[2] << std::endl;
  std::cout << "Squared distance to closest point: " << closestPointDist2 << std::endl;
  std::cout << "CellId: " << cellId << std::endl;

  auto testSource = vtkSmartPointer<vtkSphereSource>::New();
  testSource->SetRadius(0.01);
  testSource->SetCenter(testPoint);
  testSource->Update();

  auto pointSource = vtkSmartPointer<vtkSphereSource>::New();
  pointSource->SetRadius(0.01);
  pointSource->SetCenter(closestPoint);
  pointSource->Update();

  vtkSmartPointer<vtkPolyDataMapper> sphereMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
  sphereMapper->SetInputConnection(sphereSource->GetOutputPort());
  vtkSmartPointer<vtkPolyDataMapper> testMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
  testMapper->SetInputConnection(testSource->GetOutputPort());
  vtkSmartPointer<vtkPolyDataMapper> pointMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
  pointMapper->SetInputConnection(pointSource->GetOutputPort());

  auto sphereActor = vtkSmartPointer<vtkActor>::New();
  sphereActor->SetMapper(sphereMapper);
  sphereActor->GetProperty()->EdgeVisibilityOn();
  auto pointActor = vtkSmartPointer<vtkActor>::New();
  pointActor->SetMapper(pointMapper);
  pointActor->GetProperty()->SetColor(1, 0, 0);
  auto testActor = vtkSmartPointer<vtkActor>::New();
  testActor->SetMapper(testMapper);
  testActor->GetProperty()->SetColor(0, 1, 0);

  auto render = vtkSmartPointer<vtkRenderer>::New();
  render->AddActor(sphereActor);
  render->AddActor(pointActor);
  render->AddActor(testActor);

  auto renWin = vtkSmartPointer<vtkRenderWindow>::New();
  renWin->SetSize(640, 480);
  renWin->AddRenderer(render);

  auto interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
  interactor->SetRenderWindow(renWin);

  renWin->Render();
  interactor->Initialize();
  interactor->Start();
  
  return EXIT_SUCCESS;
}

VTK笔记——寻找最近点(vtkCellLocator)在Mesh上找最近点_第3张图片

之前点对点寻找效果不是想要的,如下
VTK笔记——寻找最近点(vtkCellLocator)在Mesh上找最近点_第4张图片
现在用点到面寻找的结果就很好,如下

VTK笔记——寻找最近点(vtkCellLocator)在Mesh上找最近点_第5张图片

你可能感兴趣的:(VTK)