VTK 判断一个 点 是否在一个模型 stl 内部 vtk 点是否在内部 表面 寻找最近点

news2024/9/21 11:21:34

判断 一个点 ,判断是否在风格 stl 模型内部,或表面:

目录

1.方案一:使用vtkCellLocator  FindClosestPoint 找到模型上距离给定点最近的一点,计算两点的距离 ,小于某一阈值 则认为此点在模型上;

2.方案二 使用 vtkKdTreePointLocator

3.方案三 使用 vtkSelectEnclosedPoints


1.方案一:使用vtkCellLocator  FindClosestPoint 找到模型上距离给定点最近的一点,计算两点的距离 ,小于某一阈值 则认为此点在模型上;

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

bool CheckPointInsidePolyData(vtkPolyData * poly, double* pt)
{
	bool inside=false; 
	auto cellLocator = vtkSmartPointer<vtkCellLocator>::New();
	cellLocator->SetDataSet(poly);
	cellLocator->BuildLocator();
	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=-1;
	cellLocator->FindClosestPoint(point, closestPoint, assistCell, cellId, subId, closestPointDist2);
 
	if (-1!= subId&&closestPointDist2 < 0.001)
	{
		return true;
	}
	return inside;
}

2.方案二 使用 vtkKdTreePointLocator

但这个只能找到最新的点,还需要自己判断一下距离

官方样例:

#include <vtkIdList.h>
#include <vtkKdTreePointLocator.h>
#include <vtkNew.h>
#include <vtkPoints.h>
#include <vtkPolyData.h>

int main(int, char*[])
{
  // Setup point coordinates
  double x[3] = {1.0, 0.0, 0.0};
  double y[3] = {0.0, 1.0, 0.0};
  double z[3] = {0.0, 0.0, 1.0};

  vtkNew<vtkPoints> points;
  points->InsertNextPoint(x);
  points->InsertNextPoint(y);
  points->InsertNextPoint(z);

  vtkNew<vtkPolyData> polydata;
  polydata->SetPoints(points);

  // Create the tree
  vtkNew<vtkKdTreePointLocator> kDTree;
  kDTree->SetDataSet(polydata);
  kDTree->BuildLocator();

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

  // Find the closest points to TestPoint
  vtkIdType iD = kDTree->FindClosestPoint(testPoint);
  std::cout << "The closest point is point " << iD << std::endl;

  // Get the coordinates of the closest point
  double closestPoint[3];
  kDTree->GetDataSet()->GetPoint(iD, closestPoint);
  std::cout << "Coordinates: " << closestPoint[0] << " " << closestPoint[1]
            << " " << closestPoint[2] << std::endl;

  return EXIT_SUCCESS;
}

3.方案三 使用 vtkSelectEnclosedPoints

vtkSelectEnclosedPoints类可以判断标记点是否在封闭表面内。
vtkSelectEnclosedPoints是一个Filter,它计算所有输入点以确定它们是否位于封闭曲面中。过滤器生成一个(0,1)掩码(以vtkDataArray的形式),指示点是在提供的曲面的外部(掩码值=0)还是内部(掩码值=1)(输出vtkDataArray的名称是“SelectedPoints”。)
运行过滤器后,可以通过调用IsInside(ptId)方法来查询点是否在内部/外部。

样例:判断三个点是否在立方体内

注意:在立方体边上的点,不属于在立方体内部;

 CODE

#include <vtkVersion.h>
#include <vtkPolyData.h>
#include <vtkPointData.h>
#include <vtkCubeSource.h>
#include <vtkSmartPointer.h>
#include <vtkSelectEnclosedPoints.h>
#include <vtkIntArray.h>
#include <vtkDataArray.h>
#include <vtkProperty.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>

int main(int, char*[])
{

	vtkNew<vtkCubeSource> cubeSource;
	cubeSource->Update();

	vtkPolyData* cube = cubeSource->GetOutput();

	double testInside[3] = { 0.0, 0.0, 0.0 };
	double testOutside[3] = { 0.7, 0.0, 0.0 };
	double testBorderOutside[3] = { 0.5, 0.0, 0.0 };
	vtkNew<vtkPoints> points;
	points->InsertNextPoint(testInside);
	points->InsertNextPoint(testOutside);
	points->InsertNextPoint(testBorderOutside);

	vtkNew<vtkPolyData> pointsPolydata;
	pointsPolydata->SetPoints(points);

	//Points inside test
	vtkNew<vtkSelectEnclosedPoints> selectEnclosedPoints;
	selectEnclosedPoints->SetInputData(pointsPolydata);
	selectEnclosedPoints->SetSurfaceData(cube);
	selectEnclosedPoints->Update();

	for (unsigned int i = 0; i < 3; i++) {
		std::cout << "Point " << i << ": " << selectEnclosedPoints->IsInside(i) << std::endl;
	}

	vtkDataArray* insideArray = vtkDataArray::SafeDownCast(selectEnclosedPoints->GetOutput()->GetPointData()->GetArray("SelectedPoints"));

	for (vtkIdType i = 0; i < insideArray->GetNumberOfTuples(); i++) {
		std::cout << i << " : " << insideArray->GetComponent(i, 0) << std::endl;
	}
	//Cube mapper, actor
	vtkNew<vtkPolyDataMapper> cubeMapper;
	cubeMapper->SetInputConnection(cubeSource->GetOutputPort());

	vtkNew<vtkActor> cubeActor;
	cubeActor->SetMapper(cubeMapper);
	cubeActor->GetProperty()->SetOpacity(0.5);

	//First, apply vtkVertexGlyphFilter to make cells around points, vtk only render cells.
	vtkNew<vtkVertexGlyphFilter> vertexGlyphFilter;

	vertexGlyphFilter->AddInputData(pointsPolydata);
	vertexGlyphFilter->Update();

	vtkNew<vtkPolyDataMapper> pointsMapper;
	pointsMapper->SetInputConnection(vertexGlyphFilter->GetOutputPort());

	vtkNew<vtkActor> pointsActor;
	pointsActor->SetMapper(pointsMapper);
	pointsActor->GetProperty()->SetPointSize(5); 
	pointsActor->GetProperty()->SetColor(1.0, 0.0, 0);

	//Create a renderer, render window, and interactor
	vtkNew<vtkRenderer> renderer;
	vtkNew<vtkRenderWindow> renderWindow;
	renderWindow->AddRenderer(renderer);
	vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;
	renderWindowInteractor->SetRenderWindow(renderWindow);

	// Add the actor to the scene
	renderer->AddActor(cubeActor);
	renderer->AddActor(pointsActor);
	renderer->SetBackground(.0, 1, .0);

	renderWindow->Render();
	renderWindowInteractor->Start();
	return EXIT_SUCCESS;
}
 
 

输出:

Point 0: 1
Point 1: 0
Point 2: 0
0 : 1
1 : 0
2 : 0

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/891706.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Esp8266学习7. 点亮JMD0.96C-1 OLED屏

Esp8266学习7. 点亮JMD0.96C-1 OLED屏 一、ESP32-C3 I2C资源简介1. 简介2. 准备工作 二、I2C协议简介1. 起始条件&#xff08;Start Condition&#xff09;&#xff1a;2. 设备地址传输&#xff08;Device Address Transmission&#xff09;&#xff1a;3. 从设备响应&#xff…

玩转单元测试之gtest

引言 程序开发的时候&#xff0c;往往需要编写一些测试样例来完成功能测试&#xff0c;以保证自己的代码在功能上符合预期&#xff0c;能考虑到一些异常边界问题等等。 gtest快速入门 1.引入gtest # 使用的是1.10版本&#xff0c;其他版本可根据需要选择 git clone -b v1.1…

踩坑经验:JavaScript 中的 for...of 和 for...in 循环

在 JavaScript 编程中&#xff0c;for...of 和 for...in 是常用的循环语法&#xff0c;但它们在使用时可能会引发一些意想不到的问题。本文将分享我在使用这两种循环时所遇到的坑和经验。 两者的区别&#xff1a; 适用对象类型&#xff1a; for…of&#xff1a;主要用于遍历可…

微信开发之一键删除好友的技术实现

简要描述&#xff1a; 删除联系人 请求URL&#xff1a; http://域名地址/delContact 请求方式&#xff1a; POST 请求头Headers&#xff1a; Content-Type&#xff1a;application/jsonAuthorization&#xff1a;login接口返回 参数&#xff1a; 参数名必选类型说明wI…

小红书运营 新号快速涨粉方法

大家好&#xff0c;我是网媒智星&#xff0c;今天跟大家分享一下小红书新号快速涨粉的方法。 新手博主在刚开始使用小红书时往往会陷入一个误区&#xff0c;他们热衷于发布自己认可的笔记&#xff0c;然后迫不及待地去查看数据&#xff0c;却发现没有获得赞赏和关注。 然而&…

微信小程序登录及登录态管理

一&#xff0c;小程序登录 小程序登录 | 微信开放文档 接口应在服务器端调用&#xff0c;详细说明参见服务端API。 接口说明 接口英文名 code2Session 功能描述 登录凭证校验。通过 wx.login 接口获得临时登录凭证 code 后传到开发者服务器调用此接口完成登录流程。更多使…

Android Framework 全局替换系统字体

基于Android 11 Android Framework 全局替换系统字体 第一种通过替换系统默认字体 将需要替换的字体资源放置frameworks/base/data/fonts/目录下。 将系统默认的Roboto字体替换为HarmonyOs字体。 frameworks/base/data/fonts/fonts.xml frameworks/base/data/fonts/Android.…

Docker容器与虚拟化技术:Docker镜像创建、Dockerfile实例

目录 一、理论 1.Docker镜像的创建方法 2.Docker镜像结构的分层 3.Dockerfile 案例 4.构建Systemctl镜像&#xff08;基于SSH镜像&#xff09; 5.构建Tomcat 镜像 6.构建Mysql镜像 二、实验 1.Docker镜像的创建 2. Dockerfile 案例 3.构建Systemctl镜像&#xff08;…

AI抢饭碗!新闻集团将使用生成式AI,每周自动写3000篇新闻丨IDCF

作者&#xff1a;AIGC开放社区 8月1日&#xff0c;英国卫报消息&#xff0c;全球最大新闻媒体公司之一的新闻集团&#xff0c;将使用生成式AI每周自动创建3000篇澳大利亚本地新闻。 据悉&#xff0c;新闻集团在内部成立了一个名为“Data Local”的部门只有4名员工&#xff0c;…

爱校对:塑造无瑕公文的强大工具

在公文处理的世界中&#xff0c;每个字、每个标点都需要细心打磨&#xff0c;确保无一瑕疵。如何能达到这种精确无误的程度呢&#xff1f;让我们一起来看看强大的爱校对软件如何帮助我们塑造无瑕的公文。 首先&#xff0c;爱校对软件采用先进的自然语言处理和深度学习技术&…

IDA远程调试真机app

IDA远程调试真机app 第一步&#xff1a;启动 android_server&#xff0c;并修改端口 # 启动android_server ./android_server -p31928第二步&#xff1a;端口转发、挂起程序 # 端口转发adb forward tcp:31928 tcp:31928# 挂起程序 adb shell am start -D -n com.qianyu.antid…

shell和Python 两种方法分别画 iostat的监控图

在服务器存储的测试中,经常需要看performance的性能曲线&#xff0c;这样最能直接观察HDD或者SSD的性能曲线。 如下这是一个针对HDD跑Fio读写的iostat监控log,下面介绍一下分别用shell 和Python3 写画iostat图的方法 1 shell脚本 环境:linux OS gnuplot工具 第一步 :解析iosta…

Mysql分表后同结构不同名称表之间复制数据以及Update语句只更新日期加减不更改时间

场景 SpringBootMybatis定时任务实现大数据量数据分表记录和查询&#xff1a; SpringBootMybatis定时任务实现大数据量数据分表记录和查询_mybatis 定时任务创建日表_霸道流氓气质的博客-CSDN博客 通过以上分表实现的同结构不同表名之间的表&#xff0c;如何将一个表中的数据…

Flink学习笔记(一)

流处理 批处理应用于有界数据流的处理&#xff0c;流处理则应用于无界数据流的处理。 有界数据流&#xff1a;输入数据有明确的开始和结束。 无界数据流&#xff1a;输入数据没有明确的开始和结束&#xff0c;或者说数据是无限的&#xff0c;数据通常会随着时间变化而更新。 在…

python模块中的_all__属性的作用

文章目录 前言 一、python模块中的_all__属性的作用 总结 前言 python模块中的特殊变量_all__的用法总结。 一、python模块中的_all__属性的作用 顾名思义&#xff1a;我们如果导一个包里面的函数或者变量&#xff0c;会把暴露在外部的变量和函数导出。那么有些变量或者函…

如何做好小程序的运营,有哪些运营策略?

小程序用完即走的特性&#xff0c;使得小程序留存用户比较困难。任何一个产品的出现&#xff0c;绕不过推广运营这个话题&#xff0c;小程序也是一样。抓住用户&#xff0c;培养用户的忠诚度是所有产品的根本&#xff0c;我们该怎样从零开始运营好小程序&#xff1f; 一、人群…

免费批量ppt转pdf?一个方法教你完美转换

随着科技的不断发展&#xff0c;电子文档的使用越来越普遍。在商业、教育和个人领域&#xff0c;我们经常需要将PPT文件转换为PDF格式&#xff0c;以便更方便地共享和存档。幸运的是&#xff0c;现在有许多在线工具和软件可以帮助我们轻松地完成免费批量ppt转pdf。下面将介绍一…

LabVIEW开发设计热稳定器

LabVIEW开发设计热稳定器 使用与PC控制单元接口的电子设备进行数据采集和控制已广泛用于不同的工业应用。精确的温度控制是一个巨大的挑战&#xff0c;这就是为什么一些工业应用需要使用适当的材料和设备比更好的温度精度。 ​ 为了追踪[-50至250C]之间的温度变化&#xff0c…

【LeetCode】205. 同构字符串

205. 同构字符串&#xff08;简单&#xff09; 方法&#xff1a;哈希映射 思路 判断两个字符串是不是同构字符串&#xff0c;只需要判断对应的字符是不是存在映射关系&#xff0c;我们可以使用 map 来保存字符间的映射关系。由于 “不同字符不能映射到同一个字符上&#xff0…

babylonjs基于自定义网格生成围栏动画

效果&#xff1a; import { Vector3, Mesh, MeshBuilder, StandardMaterial, Texture, Animation, Color3 } from "babylonjs/core"; import imgUrl from "./image/headerwangge2.png" // 创建模型护栏特效 export default class CreateRail {constructor…