欢迎大家加入VTK社区雪易VTK社区-CSDN社区云
小结:本博文主要针对VTK中的PointLocator的分类及各接口的用途进行讲解,PointLocator主要用途为点的位置计算,希望能为各位小伙伴有所帮助。
vtk中关于Locator的关系图
目录
vtkLocator
vtkAbstractPointLocator
vtkIncrementalPointLocator
vtkIncrementalOctreePointLocator
vtkPointLocator
vtkMergePoints
vtkNonMergingPointLocator
vtkKdTreePointLocator
vtkOctreePointLocator
vtkStaticPointLocator
vtkStaticPointLocator2D
vtkLocator
描述:vtkLocator是空间搜索对象或定位对象的基类。vtkLocator的工作原理是将三维空间切分为很多小区域,这样在点定位、线相交和对象之间的相交的问题求解时,可以快速给出响应。
vtkLocator作为基类,为所有的Locator接口提供数据成员和方法。
Locator的工作原理如下:
1. 在Locator划分的区域中插入一个或多个“entities”,比如Point或者Cell。这些“entities”占一个或多个区域。
2. 执行几何操作时,先对区域进行操作,若结果为正,则对区域中的“entities”进行操作。例如在碰撞测试时,首先碰撞定位器识别相交的区域,若发现交集,在对区域中的"entities"进行相交计算。
为了提高速度,Locator采用树形结构。
vtkAbstractPointLocator
描述: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);
//@}
vtkIncrementalPointLocator
描述:vtkIncreamentalPointLocator是一个既支持点定位也支持点插入的基类。
该Filter可支持点插入功能,搜索结构保持动态增加。以下是两个支持插入点的Filter。vtkIncrementalOctreePointLocator是vtkPointLocator所有功能的基于八叉树的加速实现。
vtkPointLocator
描述:vtkPointLocator是一个在3D中快速定位点的类。它将3D空间划分为规则的区域,将将Points放置在这些区域中。一个典型的操作就是找出给定点的最近点。
vtkPointLocator有两种不同的交互方法。在第一种方法中,您为它提供一个数据集,它对数据集中的点进行操作。在第二种方法中,为它提供一个点数组,对象对数组进行操作。
vtkMergePoints
描述: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<float>(x[0]);
f[1] = static_cast<float>(x[1]);
f[2] = static_cast<float>(x[2]);
vtkFloatArray* floatArray = static_cast<vtkFloatArray*>(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 interface
double* 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<float>(x[0]);
f[1] = static_cast<float>(x[1]);
f[2] = static_cast<float>(x[2]);
float* floatArray = static_cast<vtkFloatArray*>(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 parameter
id = ptId;
return 0;
}
}
}
else
{
// Using the double interface
double* 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 parameter
id = ptId;
return 0;
}
}
}
}
else
{
// create a bucket point list and insert the point
bucket = vtkIdList::New();
bucket->Allocate(this->NumberOfPointsPerBucket / 2, this->NumberOfPointsPerBucket / 3);
this->HashTable[idx] = bucket;
}
// point has to be added
bucket->InsertNextId(this->InsertionPointId);
this->Points->InsertPoint(this->InsertionPointId, x);
id = this->InsertionPointId++;
return 1;
}
vtkNonMergingPointLocator
描述:作为vtkPointLocator的一个特殊子类,vtkNonMergingPointLocator用于直接/无检查地将点插入到vtkPoints对象中。换句话说,任何给定的点总是直接插入的。这个名字强调了这个类与其兄弟类vtkMergePoints之间的区别,后者通过利用父类vtkPointLocator使用的统一bin机制来执行基于检查的零容忍点插入(或“合并”完全重复/重合的点)。vtkPointLocator允许一般(零和非零)公差点插入以及点定位。
vtkIncrementalOctreePointLocator
vtkKdTreePointLocator
vtkOctreePointLocator
vtkStaticPointLocator
vtkStaticPointLocator2D