使用 VTK 中的单元定位器来查找最近的点

文章介绍了VTK库中用于空间搜索的两种类:vtkCellLocator和其优化版本vtkCellTreeLocator。重点讲解了它们的区别,尤其是在处理大型数据集时的效率提升。通过实例展示了如何在代码中使用这两个类进行空间查询操作。
摘要由CSDN通过智能技术生成

开发环境:

  1. Windows 11 家庭中文版
  2. Microsoft Visual Studio Community 2019
  3. VTK-9.3.0.rc0
  4. vtk-example

demo解决问题:使用 VTK 中的单元定位器来查找最近的点
在这里插入图片描述

关键点:

  1. 创建了一个球体数据源,并使用它构建了一个单元定位器(cell locator)。
  2. 通过 FindClosestPoint 方法查找了测试点的最近点,并输出了最近点的坐标、到最近点的距离的平方以及包含最近点的单元格的 ID。
  3. vtkCellTreeLocator vtkCellLocator的区别是什么?
vtkCellLocator 和 vtkCellTreeLocator 都是 VTK 中用于空间搜索的类,但它们之间存在一些区别。

vtkCellLocator 是 VTK 中用于查找单元格的类,它构建了一个内部的空间数据结构,用于高效地定位数据集中的单元格。它提供了多种方法,如查找距离给定点最近的单元格、查找被一条线穿过的所有单元格等。它适用于一般的空间搜索和相交检测。而 vtkCellTreeLocator 是 vtkCellLocator 的一个特定类型,它使用了一种叫做 "cell tree" 的数据结构来组织数据,以提高空间搜索的效率。相比于普通的 vtkCellLocator,vtkCellTreeLocator 在某些情况下可能具有更快的查询速度,特别是对于大型数据集和高维数据。

因此,可以说 vtkCellTreeLocator 是 vtkCellLocator 的一种优化实现,专门用于处理更复杂的空间搜索情况。当使用VTK进行空间搜索时,例如在三维数据集中查找最近的单元格或执行射线投射,您可以选择使用vtkCellLocator或vtkCellTreeLocator。

举个例子,如果您有一个非常大的三维数据集,比如地质模型或医学图像,您想要在其中执行大量的空间查询操作,那么使用vtkCellTreeLocator可能会比vtkCellLocator更有效率。因为vtkCellTreeLocator使用了一种更高效的数据结构,可以在大型和高维数据集中提供更快的查询速度。

另一方面,如果您的数据集相对较小,或者您只需要进行少量的空间查询操作,那么使用普通的vtkCellLocator可能已经足够满足您的需求。

因此,在选择使用哪种空间搜索类时,您可以根据您的具体应用场景和性能需求来决定。

prj name: CellLocator

#include <vtkCellLocator.h>
#include <vtkNew.h>
#include <vtkSphereSource.h>

int main(int, char*[])
{
  vtkNew<vtkSphereSource> sphereSource;
  sphereSource->Update();

  // Create the tree
  vtkNew<vtkCellLocator> cellLocator;
  cellLocator->SetDataSet(sphereSource->GetOutput());
  cellLocator->BuildLocator();

  double testPoint[3] = {2.0, 0.0, 0.0};

  // Find the closest points to TestPoint
  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;        // this is rarely used (in triangle strips only, I believe)
  cellLocator->FindClosestPoint(testPoint, closestPoint, 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;

  return EXIT_SUCCESS;
}

project name: CellTreeLocator

#include <vtkCellTreeLocator.h>
#include <vtkGenericCell.h>
#include <vtkNew.h>
#include <vtkSphereSource.h>

// Note that:
// vtkCellTreeLocator moved from vtkFiltersGeneral to vtkCommonDataModel in
// VTK commit 4a29e6f7dd9acb460644fe487d2e80aac65f7be9

int main(int, char*[])
{
  vtkNew<vtkSphereSource> sphereSource;
  sphereSource->SetCenter(0.0, 0.0, 0.0);
  sphereSource->SetRadius(1.0);
  sphereSource->Update();

  // Create the tree.
  vtkNew<vtkCellTreeLocator> cellTree;
  cellTree->SetDataSet(sphereSource->GetOutput());
  cellTree->BuildLocator();

  double testInside[3] = {0.5, 0.0, 0.0};
  double testOutside[3] = {10.0, 0.0, 0.0};

  double pcoords[3], weights[3];

  vtkIdType cellId;

  vtkNew<vtkGenericCell> cell;

  int returnValue = EXIT_SUCCESS;

  // Should be inside.
  cellId = cellTree->FindCell(testInside, 0, cell, pcoords, weights);
  if (cellId >= 0)
  {
    std::cout << "First point: in cell " << cellId << std::endl;
  }
  else
  {
    std::cout << "ERROR: Cell was not found but should have been." << std::endl;
    returnValue = EXIT_FAILURE;
  }

  // Should be outside.
  cellId = cellTree->FindCell(testOutside, 0, cell, pcoords, weights);
  if (cellId >= 0)
  {
    std::cout << "ERROR: Found point in cell " << cellId
              << " but it should be outside the domain." << std::endl;
    returnValue = EXIT_FAILURE;
  }
  else
  {
    std::cout << "Second point: outside" << std::endl;
  }

  return returnValue;
}

  • 9
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
VTK是用于可视化和图形处理的C++库,但是也可以使用Python接口来使用它。要在VTK构建单元面,可以使用vtkCellArray类。以下是一个简单的示例: ```python import vtk # 创建一个vtkPoints对象,用于存储坐标 points = vtk.vtkPoints() points.InsertNextPoint(0, 0, 0) # 添加第一个 points.InsertNextPoint(1, 0, 0) # 添加第二个 points.InsertNextPoint(1, 1, 0) # 添加第三个 # 创建一个vtkCellArray对象,用于存储单元cells = vtk.vtkCellArray() # 添加一个三角形到单元面 triangle = vtk.vtkTriangle() triangle.GetPointIds().SetId(0, 0) # 设置第一个的ID triangle.GetPointIds().SetId(1, 1) # 设置第二个的ID triangle.GetPointIds().SetId(2, 2) # 设置第三个的ID cells.InsertNextCell(triangle) # 创建一个vtkPolyData对象,将单元面添加到其 polydata = vtk.vtkPolyData() polydata.SetPoints(points) polydata.SetPolys(cells) # 创建一个vtkPolyDataMapper对象,将vtkPolyData对象映射到图形管道 mapper = vtk.vtkPolyDataMapper() mapper.SetInputData(polydata) # 创建一个vtkActor对象,将vtkPolyDataMapper对象添加到其 actor = vtk.vtkActor() actor.SetMapper(mapper) # 创建一个vtkRenderer对象,将vtkActor对象添加到其 renderer = vtk.vtkRenderer() renderer.AddActor(actor) # 创建一个vtkRenderWindow对象,将vtkRenderer对象添加到其 render_window = vtk.vtkRenderWindow() render_window.AddRenderer(renderer) # 创建一个vtkRenderWindowInteractor对象 interactor = vtk.vtkRenderWindowInteractor() interactor.SetRenderWindow(render_window) # 开始渲染 render_window.Render() interactor.Start() ``` 在上面的代码,我们首先创建一个vtkPoints对象来存储坐标,然后创建一个vtkCellArray对象来存储单元面。我们添加一个三角形到单元,并将单元面添加到vtkPolyData对象。然后,我们使用vtkPolyDataMapper将vtkPolyData对象映射到图形管道,并将其添加到vtkActor对象。最后,我们创建一个vtkRenderWindow对象来显示渲染结果,并使用vtkRenderWindowInteractor对象来处理用户交互事件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值