欢迎大家加入VTK社区雪易VTK社区-CSDN社区云
小结:本博文主要针对VTK中的PointLocator的分类及各接口的用途进行讲解,PointLocator主要用途为点的位置计算,希望能为各位小伙伴有所帮助。
vtk中关于Locator的关系图

目录
vtkLocator
vtkAbstractPointLocator
vtkIncrementalPointLocator
vtkIncrementalOctreePointLocator
vtkPointLocator
vtkMergePoints
vtkNonMergingPointLocator
vtkKdTreePointLocator
vtkOctreePointLocator
vtkStaticPointLocator
vtkStaticPointLocator2D
描述:vtkLocator是空间搜索对象或定位对象的基类。vtkLocator的工作原理是将三维空间切分为很多小区域,这样在点定位、线相交和对象之间的相交的问题求解时,可以快速给出响应。
vtkLocator作为基类,为所有的Locator接口提供数据成员和方法。
Locator的工作原理如下:
1. 在Locator划分的区域中插入一个或多个“entities”,比如Point或者Cell。这些“entities”占一个或多个区域。
2. 执行几何操作时,先对区域进行操作,若结果为正,则对区域中的“entities”进行操作。例如在碰撞测试时,首先碰撞定位器识别相交的区域,若发现交集,在对区域中的"entities"进行相交计算。
为了提高速度,Locator采用树形结构。
描述:vtkAbstractPointLocator是一个在3D中快速定位点的基类。它将3D空间划分为规则的区域,将将Points放置在这些区域中。一个典型的操作就是找出给定点的最近点。
三个常用的虚函数
//@{/*** Given a position x, return the id of the point closest to it. Alternative* method requires separate x-y-z values.* These methods are thread safe if BuildLocator() is directly or* indirectly called from a single thread first.*/virtual vtkIdType FindClosestPoint(const double x[3]) = 0;vtkIdType FindClosestPoint(double x, double y, double z);//@}/*** Given a position x and a radius r, return the id of the point* closest to the point in that radius.* dist2 returns the squared distance to the point.*/virtual vtkIdType FindClosestPointWithinRadius(double radius, const double x[3], double& dist2) = 0;//@{/*** Find the closest N points to a position. This returns the closest* N points to a position. A faster method could be created that returned* N close points to a position, but necessarily the exact N closest.* The returned points are sorted from closest to farthest.* These methods are thread safe if BuildLocator() is directly or* indirectly called from a single thread first.*/virtual void FindClosestNPoints(int N, const double x[3], vtkIdList* result) = 0;void FindClosestNPoints(int N, double x, double y, double z, vtkIdList* result);//@}//@{/*** Find all points within a specified radius R of position x.* The result is not sorted in any specific manner.* These methods are thread safe if BuildLocator() is directly or* indirectly called from a single thread first.*/virtual void FindPointsWithinRadius(double R, const double x[3], vtkIdList* result) = 0;void FindPointsWithinRadius(double R, double x, double y, double z, vtkIdList* result);//@}
描述:vtkIncreamentalPointLocator是一个既支持点定位也支持点插入的基类。
该Filter可支持点插入功能,搜索结构保持动态增加。以下是两个支持插入点的Filter。vtkIncrementalOctreePointLocator是vtkPointLocator所有功能的基于八叉树的加速实现。
描述:vtkPointLocator是一个在3D中快速定位点的类。它将3D空间划分为规则的区域,将将Points放置在这些区域中。一个典型的操作就是找出给定点的最近点。
vtkPointLocator有两种不同的交互方法。在第一种方法中,您为它提供一个数据集,它对数据集中的点进行操作。在第二种方法中,为它提供一个点数组,对象对数组进行操作。
描述:vtkMergePoints是一个定位器对象,用于快速定位3D中的点。
vtkMergePoints与其父类vtkPointLocator之间的主要区别是vtkMergePoints精确地合并重合点,因此要快得多。
//@{/*** Determine whether point given by x[3] has been inserted into points list.* Return id of previously inserted point if this is true, otherwise return* -1.* 判断点x是否被插入到点列表中,若插入则但会id,若没有插入则返回-1*/vtkIdType IsInsertedPoint(const double x[3]) override;vtkIdType IsInsertedPoint(double x, double y, double z) override{return this->vtkPointLocator::IsInsertedPoint(x, y, z);}//@}
//实现步骤
//定位点x所在的Bucket的id
//查看id是否在Table表中,若不在,则表示该点不在点列表中
//若存在,则获取Bucket中的点,并于点下进行比较,返回一致点的Id
vtkIdType vtkMergePoints::IsInsertedPoint(const double x[3])
{//// Locate bucket that point is in.//vtkIdType idx = this->GetBucketIndex(x);vtkIdList* bucket = this->HashTable[idx];if (!bucket){return -1;}else // see whether we've got duplicate point{//// Check the list of points in that bucket.//vtkIdType ptId;vtkIdType nbOfIds = bucket->GetNumberOfIds();// For efficiency reasons, we break the data abstraction for points// and ids (we are assuming and vtkIdList// is storing ints).vtkDataArray* dataArray = this->Points->GetData();vtkIdType* idArray = bucket->GetPointer(0);if (dataArray->GetDataType() == VTK_FLOAT){float f[3];f[0] = static_cast(x[0]);f[1] = static_cast(x[1]);f[2] = static_cast(x[2]);vtkFloatArray* floatArray = static_cast(dataArray);float* pt;for (vtkIdType i = 0; i < nbOfIds; i++){ptId = idArray[i];pt = floatArray->GetPointer(0) + 3 * ptId;if (f[0] == pt[0] && f[1] == pt[1] && f[2] == pt[2]){return ptId;}}}else{// Using the double interfacedouble* pt;for (vtkIdType i = 0; i < nbOfIds; i++){ptId = idArray[i];pt = dataArray->GetTuple(ptId);if (x[0] == pt[0] && x[1] == pt[1] && x[2] == pt[2]){return ptId;}}}}return -1;
}
/*** Determine whether point given by x[3] has been inserted into points list.* Return 0 if point was already in the list, otherwise return 1. If the* point was not in the list, it will be ADDED. In either case, the id of* the point (newly inserted or not) is returned in the ptId argument.* Note this combines the functionality of IsInsertedPoint() followed* by a call to InsertNextPoint().* 判断点x是否加入到点列表中,若已加入则返回0,否则返回1。* 若点x未在点列表中,则会将其加入。加入的id将会在ptId中返回。*/int InsertUniquePoint(const double x[3], vtkIdType& ptId) override;
//实现步骤
//定位点x所在的Bucket的id
//查看id是否在Table表中
//若存在,则获取Bucket中的点,并于点下进行比较,若存在一致点则返回0,Id为一致点的Id
//若不存在,则通过InsertNextId和InsertPoint将该点添加,并Id设为一致点的Id
int vtkMergePoints::InsertUniquePoint(const double x[3], vtkIdType& id)
{//// Locate bucket that point is in.//vtkIdType idx = this->GetBucketIndex(x);vtkIdList* bucket = this->HashTable[idx];if (bucket) // see whether we've got duplicate point{//// Check the list of points in that bucket.//vtkIdType ptId;vtkIdType nbOfIds = bucket->GetNumberOfIds();// For efficiency reasons, we break the data abstraction for points// and ids (we are assuming vtkPoints stores a vtkIdList// is storing ints).vtkDataArray* dataArray = this->Points->GetData();vtkIdType* idArray = bucket->GetPointer(0);if (dataArray->GetDataType() == VTK_FLOAT){float f[3];f[0] = static_cast(x[0]);f[1] = static_cast(x[1]);f[2] = static_cast(x[2]);float* floatArray = static_cast(dataArray)->GetPointer(0);float* pt;for (vtkIdType i = 0; i < nbOfIds; ++i){ptId = idArray[i];pt = floatArray + 3 * ptId;if (f[0] == pt[0] && f[1] == pt[1] && f[2] == pt[2]){// point is already in the list, return 0 and set the id parameterid = ptId;return 0;}}}else{// Using the double interfacedouble* pt;for (vtkIdType i = 0; i < nbOfIds; ++i){ptId = idArray[i];pt = dataArray->GetTuple(ptId);if (x[0] == pt[0] && x[1] == pt[1] && x[2] == pt[2]){// point is already in the list, return 0 and set the id parameterid = ptId;return 0;}}}}else{// create a bucket point list and insert the pointbucket = vtkIdList::New();bucket->Allocate(this->NumberOfPointsPerBucket / 2, this->NumberOfPointsPerBucket / 3);this->HashTable[idx] = bucket;}// point has to be addedbucket->InsertNextId(this->InsertionPointId);this->Points->InsertPoint(this->InsertionPointId, x);id = this->InsertionPointId++;return 1;
}
描述:作为vtkPointLocator的一个特殊子类,vtkNonMergingPointLocator用于直接/无检查地将点插入到vtkPoints对象中。换句话说,任何给定的点总是直接插入的。这个名字强调了这个类与其兄弟类vtkMergePoints之间的区别,后者通过利用父类vtkPointLocator使用的统一bin机制来执行基于检查的零容忍点插入(或“合并”完全重复/重合的点)。vtkPointLocator允许一般(零和非零)公差点插入以及点定位。