VTK中如何 搜索 目标点 最近的点或者点集( vtkPointLocator )

15 篇文章 0 订阅
3 篇文章 0 订阅

背景:

        在vtk使用过程中,我们有时要搜索点或者cell最近的 单元,  仔细看源码,有时无法判断其具体是什么样子,因而这里做了可视化处理,方便我们更深刻的理解 vtkPointLocator  类型函数的使用;

过程:

1.了解其继承关系是必要的:

 

2.开始探索该函数的一些效果:

我们会将原始数据以 绿色 小球表示,   范围 R 用白色透明标识 , 搜索到的点,用 蓝色标识

2.1. 准备数据集.

        

                std::vector<std::array<double, 3>> mPointSource;


				//vtkNew<vtkMinimalStandardRandomSequence> rm;
				准备一份数据..... 包含 几何数据,以及 拓扑数据.
				//for (size_t i = 0; i < 8; i++)
				//{
				//	//随机点
				//	auto x = rm->GetRangeValue(-10,10);
				//	rm->Next();

				//	auto y = rm->GetRangeValue(-10, 10);
				//	rm->Next();

				//	auto z = rm->GetRangeValue(-10, 10);
				//	rm->Next();
				//	std::array<double, 3> curTempValue{x,y,z};
				//	mPointSource.emplace_back(curTempValue);
				//}


				//将原始的数据,设计成一条折线.
				mPointSource.emplace_back(std::array<double, 3>{0,0,0});
				mPointSource.emplace_back(std::array<double, 3>{10, -10, 0});
				mPointSource.emplace_back(std::array<double, 3>{20, 10, 0});
				mPointSource.emplace_back(std::array<double, 3>{30, -80, 0});
				mPointSource.emplace_back(std::array<double, 3>{40, 12, 0});
				mPointSource.emplace_back(std::array<double, 3>{80, 0, 0});

2.2,具体创建过程: 

2.2.1

       FindClosestPoint () 我们先看这个函数的效果.

vtkNew<vtkPoints> mVtkPs;
				vtkNew<vtkCellArray> mTopoCells;
				for (auto& item : mPointSource)
				{
					mVtkPs->InsertNextPoint(item[0], item[1], item[2]);
				}

				//连接线.
				auto cutPNumber = mVtkPs->GetNumberOfPoints();
				for (size_t i = 1; i < cutPNumber; i++)
				{
					
					vtkNew<vtkLine> curLine;
					curLine->GetPointIds()->SetId(0, i-1);
					curLine->GetPointIds()->SetId(1, i);
					mTopoCells->InsertNextCell(curLine);
				
				}
				
				vtkNew<vtkPolyData> mPolydata;
				mPolydata->SetPoints(mVtkPs);
				mPolydata->SetLines(mTopoCells);
				
				//显示原始对象.
				auto mActor = VtkCreatorHelper::CreateActorFromInputData(mPolydata);
				mRender->AddActor(mActor);

				//显示点.
				vtkNew<vtkPolyData> mPointPolydata;
				mPointPolydata->ShallowCopy(mPolydata);
				auto mPointActor = VtkCreatorHelper::CreateActorFromInputData(mPointPolydata);
				mPointActor->GetProperty()->SetPointSize(4);
				mPointActor->GetProperty()->SetColor(0,1.0,0);
				mPointActor->GetProperty()->SetRepresentationToPoints();
				mRender->AddActor(mPointActor);



				auto printPoint = [=](std::string str, double* value) {

					std::cout << str.c_str() << "  " << value[0] << " " << value[1] << " " << value[2] << std::endl;

				};

switch (locatorType)
				{
				case 0:
				{

					//获取最近的距离...并将这个距离显示成
					{

						vtkNew<vtkPointLocator> mPointLocator; //使用点查询....
						mPointLocator->SetDataSet(mPolydata);
						mPointLocator->BuildLocator();
						mPointLocator->Update();

						VtkCreatorHelper::PrintVtkObjectInfo(mPointLocator);//输出.
						auto outFilterActor = VtkCreatorHelper::CreateActorFromBounds(mPointLocator->GetBounds());
						mRender->AddActor(outFilterActor);

						//查询一.
						int searchType = 1;
						switch (searchType)
						{
						case 0:
						{

							//查询单独的点.
							double testP[3]{ 20, 5, 0 };//20, 10, 0  1,2,3
							auto findID = mPointLocator->FindClosestPoint(testP);
							if (findID != -1)
							{
								auto findP = mPolydata->GetPoint(findID);
								printPoint("要查的点 : ", testP);
								printPoint("查找到的点: ", findP);
								auto findActor = VtkCreatorHelper::CreateVtkSphereSource(findP[0], findP[1], findP[2], 3, 1.0, 1.0, 1.0, 0.6);
								mRender->AddActor(findActor);
							}
							break;
						}

该显示效果.

 2.2.2

        FindPointsWithinRadius() 我们再来看这个函数的效果. 注意这里的半径,以及搜索列表写法.

case 1:
						{
							//按照半径,查询
							double testP[3]{ 20, 5, 0 };

							printPoint("要查的点 : ", testP);
							double R = 20;
							vtkNew<vtkIdList> mList;
							mPointLocator->FindPointsWithinRadius(R, testP, mList);

							//绘制R为半径的圆.
							auto RActor = VtkCreatorHelper::CreateVtkSphereSource(testP[0], testP[1], testP[2], R, 1.0, 1.0, 1.0, 0.3);
							mRender->AddActor(RActor);

							auto getPointsNumber = mList->GetNumberOfIds();
							for (size_t i = 0; i < getPointsNumber; i++)
							{
								auto findP = mPolydata->GetPoint(mList->GetId(i));
								printPoint("查找到的点: ", findP);
								auto findActor = VtkCreatorHelper::CreateVtkSphereSource(findP[0], findP[1], findP[2], 3, 0.0, 0.0, 1.0);
								mRender->AddActor(findActor);
							}

							break;
						}

 

2.2.3 其他的函数使用方式,都和上面 两种方式一个样子,这里改出他们的理解

	case 2:
						{

							//mPointLocator->FindClosestPointWithinRadius(); 这个本身就是在 Radius内部,查询众多点中,距离目标TestPoint最近的点.

							break;
						}
						case 3:
						{

							//mPointLocator->FindClosestInsertedPoint(); 寻找插入点,最近的点.
							break;
						}

2.2.4 特殊的一种巡点方式,是分布式.这个理解起来比较啰嗦. 我这里给出解释.

	case 4:
						{
							//mPointLocator->FindDistributedPoints(); 
							//这个没理解.仔细看一下:  这个函数是在分布式下进行查点搜寻的.  加快搜索速度,注意,结构必须也是 vtkDistributedDataSet 类型.
							/*
							需要注意的是,FindDistributedPoints 函数需要满足一定的条件才能使用。具体来说,要使用 FindDistributedPoints 函数,需要满足以下条件:
							数据集必须是 vtkDistributedDataSet 类型。
							数据集必须被正确地分割成多个部分,并且每个部分都被正确地分配给了不同的计算节点。
							数据集的每个部分必须包含一个 vtkPointSet,并且这些 vtkPointSet 必须包含完整的点坐标信息。
							如果满足以上条件,就可以在分布式计算环境中使用 FindDistributedPoints 函数进行点集操作了。
							*/
						}

希望能帮助一些想要学习vtk的小伙伴

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值