VTK笔记-图形相关-判断空间上的点是否在图元内-vtkSelectEnclosedPoints

2023-11-10

判断空间上的点是否在几何图元内,使用vtkSelectEnclosedPoints类;

vtkSelectEnclosedPoints

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

主要接口

闭合曲面

void SetSurfaceData(vtkPolyData* pd);
void SetSurfaceConnection(vtkAlgorithmOutput* algOutput);  
vtkPolyData* GetSurface();
vtkPolyData* GetSurface(vtkInformationVector* sourceInfo);

待判断点

使用vtkDataSetAlgorithm类的SetInputData设置待判定数据集,一般是点数据的vtkPoints

void SetInputData(vtkDataSet*);

查询结果

使用IsInside查询索引为inputPtId的点是否在闭合曲面中,1是在内部;0是在外部;

int IsInside(vtkIdType inputPtId);
int IsInsideSurface(double x[3]);
int IsInsideSurface(double x, double y, double z);
static int IsInsideSurface(double x[3], vtkPolyData* surface, double bds[6], double length,
     double tol, vtkAbstractCellLocator* locator, vtkIdList* cellIds, vtkGenericCell* genCell,
     vtkIntersectionCounter& counter, vtkRandomPool* poole = nullptr, vtkIdType seqIdx = 0);

示例

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

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

#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 <vtkVertexGlyphFilter.h>
#include <vtkProperty.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkVertexGlyphFilter.h>

#include "vtk_include.h"

class Test_Clip_Volume {
public:
	static void Test() {
		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 < 2; 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(0.0, 0.0, 1);

		//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();		
	}
};

在这里插入图片描述

平面外的点在平面上的投影是否落入圈选的范围

设定四个在XY平面上的点,组成了边长为1的正方形,判断点(1,1,10)在XY平面上的投影是否落入正方形内;
使用vtkPlane的ProjectPoint方法计算点(1,1,10)在XY平面上的投影点(1,1,0);
使用vtkSelectEnclosedPoints类判断投影点(1,1,0)是否在正方形内;

static float x[4][3] = { {0,0,0},{1,0,0},{1,1,0},{0,1,0} };
static vtkIdType pts[4] = {0,1,2,3};
vtkNew<vtkPolyData> cube;
vtkNew<vtkPoints> points;
vtkNew<vtkCellArray> polys;
vtkNew<vtkFloatArray> scalars;

for (int i = 0; i < 4; i++) {
	points->InsertPoint(i, x[i]);
	scalars->InsertTuple1(i, i);
}
polys->InsertNextCell(4, pts);
		
cube->SetPoints(points);		
cube->SetPolys(polys);
cube->GetPointData()->SetScalars(scalars);

double testInside[3] = { 1, 1, 10.0 };
double project_point[3] = { 0 };
vtkNew<vtkPlane> plane;
plane->SetOrigin(0.0, 0.0, 0.0);
plane->SetNormal(0.0, 0.0, 1.0);
plane->ProjectPoint(testInside, project_point);

vtkNew<vtkPoints> points1;
points1->InsertNextPoint(project_point);
vtkNew<vtkPolyData> pointsPolydata;
pointsPolydata->SetPoints(points1);

vtkNew<vtkSelectEnclosedPoints> selectEnclosedPoints;
selectEnclosedPoints->SetInputData(pointsPolydata);
selectEnclosedPoints->SetSurfaceData(cube);
selectEnclosedPoints->Update();
for (unsigned int i = 0; i < 1; i++)
{
	std::cout << "Point " << i << ": " << selectEnclosedPoints->IsInside(i) << std::endl;
}
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(0.0, 0.0, 1);

vtkNew<vtkPolyDataMapper> cubeMapper;
cubeMapper->SetInputData(cube);
cubeMapper->SetScalarRange(0, 7);
vtkNew<vtkActor> cubeActor;
cubeActor->SetMapper(cubeMapper);
vtkNew<vtkCamera> camera;
camera->SetPosition(1, 1, 1);
camera->SetFocalPoint(0, 0, 0);

vtkNew<vtkRenderer> renderer;
renderer->AddActor(pointsActor);
renderer->AddActor(cubeActor);
renderer->SetActiveCamera(camera);
renderer->ResetCamera();
renderer->SetBackground(1, 1, 1);

vtkNew<vtkRenderWindow> renWin;
renWin->AddRenderer(renderer);
renWin->SetSize(300, 300);
vtkNew<vtkRenderWindowInteractor> iren;
iren->SetRenderWindow(renWin);
renWin->Render();
iren->Initialize();
iren->Start();

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
查询结果显示,0序号的点在四边形中;
注意:在实际开发中,判断点在平面上的投影是否在圈选的范围和判断点是否在几何图元中,这两方面运用很常见,了解怎么计算和使用VTK那些类来计算,也可以试着自己使用线性代数的知识计算这两个方面的代码;有机会在补充自己写的代码;

使用vtkPolygon类的方法PointInPolygon

#include <vtkNew.h>
#include <vtkPoints.h>
#include <vtkPolygon.h>

int main(int, char*[])
{
  // Create the polygon
  vtkNew<vtkPolygon> polygon;
  polygon->GetPoints()->InsertNextPoint(0.0, 0.0, 0.0);
  polygon->GetPoints()->InsertNextPoint(1.0, 0.0, 0.0);
  polygon->GetPoints()->InsertNextPoint(1.0, 1.0, 0.0);
  polygon->GetPoints()->InsertNextPoint(0.0, 1.0, 0.0);

  double testIn[3] = {0.5, 0.5, 0.0};
  double testOut[3] = {2.0, 0.5, 0.0};

  double n[3];
  polygon->ComputeNormal(
      polygon->GetPoints()->GetNumberOfPoints(),
      static_cast<double*>(polygon->GetPoints()->GetData()->GetVoidPointer(0)),
      n);

  double bounds[6];
  polygon->GetPoints()->GetBounds(bounds);

  std::cout << "testIn in polygon? "
            << polygon->PointInPolygon(
                   testIn, polygon->GetPoints()->GetNumberOfPoints(),
                   static_cast<double*>(
                       polygon->GetPoints()->GetData()->GetVoidPointer(0)),
                   bounds, n)
            << std::endl;

  std::cout << "testOut in polygon? "
            << polygon->PointInPolygon(
                   testOut, polygon->GetPoints()->GetNumberOfPoints(),
                   static_cast<double*>(
                       polygon->GetPoints()->GetData()->GetVoidPointer(0)),
                   bounds, n)
            << std::endl;

  return EXIT_SUCCESS;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

VTK笔记-图形相关-判断空间上的点是否在图元内-vtkSelectEnclosedPoints 的相关文章

  • 结构化绑定中缺少类型信息

    我刚刚了解了 C 中的结构化绑定 但有一件事我不喜欢 auto x y some func is that auto正在隐藏类型x and y 我得抬头看看some func的声明来了解类型x and y 或者 我可以写 T1 x T2 y
  • 在模板类中声明模板友元类时出现编译器错误

    我一直在尝试实现我自己的链表类以用于教学目的 我在迭代器声明中指定了 List 类作为友元 但它似乎无法编译 这些是我使用过的 3 个类的接口 Node h define null Node
  • 调用 McAfee 病毒扫描引擎

    我收到客户的请求 要求使用他们服务器上的 McAfee 病毒扫描将病毒扫描集成到应用程序中 我做了一些调查 发现 McScan32 dll 是主要的扫描引擎 它导出各种看起来有用的函数 我还发现提到了 McAfee Scan Engine
  • STL 迭代器:前缀增量更快? [复制]

    这个问题在这里已经有答案了 可能的重复 C 中的预增量比后增量快 正确吗 如果是 为什么呢 https stackoverflow com questions 2020184 preincrement faster than postinc
  • 没有特殊字符的密码验证器

    我是 RegEx 的新手 已经进行了大量搜索 但没有找到任何具体内容 我正在编写一个验证密码字符串的正则表达式 可接受的字符串必须至少具有 4 种字符类型中的 3 种 数字 小写字母 大写字母 特殊字符 我对包含有一个想法 也就是说 如果这
  • 在一个数据访问层中处理多个连接字符串

    我有一个有趣的困境 我目前有一个数据访问层 它必须与多个域一起使用 并且每个域都有多个数据库存储库 具体取决于所调用的存储过程 目前 我只需使用 SWITCH 语句来确定应用程序正在运行的计算机 并从 Web config 返回适当的连接字
  • 如何在 Cassandra 中存储无符号整数?

    我通过 Datastax 驱动程序在 Cassandra 中存储一些数据 并且需要存储无符号 16 位和 32 位整数 对于无符号 16 位整数 我可以轻松地将它们存储为有符号 32 位整数 并根据需要进行转换 然而 对于无符号 64 位整
  • 机器Epsilon精度差异

    我正在尝试计算 C 中双精度数和浮点数的机器 epsilon 值 作为学校作业的一部分 我在 Windows 7 64 位中使用 Cygwin 代码如下 include
  • std::list 线程push_back、front、pop_front

    std list 线程安全吗 我假设不是这样 所以我添加了自己的同步机制 我认为我有正确的术语 但我仍然遇到问题 每个函数都由单独的线程调用 Thread1 不能等待 它必须尽可能快 std list
  • 如何使从 C# 调用的 C(P/invoke)代码“线程安全”

    我有一些简单的 C 代码 它使用单个全局变量 显然这不是线程安全的 所以当我使用 P invoke 从 C 中的多个线程调用它时 事情就搞砸了 如何为每个线程单独导入此函数 或使其线程安全 我尝试声明变量 declspec thread 但
  • 访问外部窗口句柄

    我当前正在处理的程序有问题 这是由于 vista Windows 7 中增强的安全性引起的 特别是 UIPI 它阻止完整性级别较低的窗口与较高完整性级别的窗口 对话 就我而言 我想告诉具有高完整性级别的窗口进入我们的应用程序 它在 XP 或
  • 重载 (c)begin/(c)end

    我试图超载 c begin c end类的函数 以便能够调用 C 11 基于范围的 for 循环 它在大多数情况下都有效 但我无法理解和解决其中一个问题 for auto const point fProjectData gt getPoi
  • 人脸 API DetectAsync 错误

    我想创建一个简单的程序来使用 Microsoft Azure Face API 和 Visual Studio 2015 检测人脸 遵循 https social technet microsoft com wiki contents ar
  • 为什么使用小于 32 位的整数?

    我总是喜欢使用最小尺寸的变量 这样效果就很好 但是如果我使用短字节整数而不是整数 并且内存是 32 位字可寻址 这真的会给我带来好处吗 编译器是否会做一些事情来增强内存使用 对于局部变量 它可能没有多大意义 但是在具有数千甚至数百万项的结构
  • 如何在 Android 中使用 C# 生成的 RSA 公钥?

    我想在无法假定 HTTPS 可用的情况下确保 Android 应用程序和 C ASP NET 服务器之间的消息隐私 我想使用 RSA 来加密 Android 设备首次联系服务器时传输的对称密钥 RSA密钥对已在服务器上生成 私钥保存在服务器
  • C++ 继承的内存布局

    如果我有两个类 一个类继承另一个类 并且子类仅包含函数 那么这两个类的内存布局是否相同 e g class Base int a b c class Derived public Base only functions 我读过编译器无法对数
  • DotNetZip:如何提取文件,但忽略zip文件中的路径?

    尝试将文件提取到给定文件夹 忽略 zip 文件中的路径 但似乎没有办法 考虑到其中实现的所有其他好东西 这似乎是一个相当基本的要求 我缺少什么 代码是 using Ionic Zip ZipFile zf Ionic Zip ZipFile
  • 在OpenGL中,我可以在坐标(5, 5)处精确地绘制一个像素吗?

    我所说的 5 5 正是指第五行第五列 我发现使用屏幕坐标来绘制东西非常困难 OpenGL 中的所有坐标都是相对的 通常范围从 1 0 到 1 0 为什么阻止程序员使用屏幕坐标 窗口坐标如此严重 最简单的方法可能是通过以下方式设置投影以匹配渲
  • MySQL Connector C/C API - 使用特殊字符进行查询

    我是一个 C 程序 我有一个接受域名参数的函数 void db domains query char name 使用 mysql query 我测试数据库中是否存在域名 如果不是这种情况 我插入新域名 char query 400 spri
  • 类型或命名空间“MyNamespace”不存在等

    我有通常的类型或命名空间名称不存在错误 除了我引用了程序集 using 语句没有显示为不正确 并且我引用的类是公共的 事实上 我在不同的解决方案中引用并使用相同的程序集来执行相同的操作 并且效果很好 顺便说一句 这是VS2010 有人有什么

随机推荐

  • 2019matlab安装

    本文转载自Matlab R2019a Win64位 迅雷下载链接 Yohaoa CSDN博客 matlab迅雷下载 和MATLAB 2019a安装教程和破解方法 附Crack文件 我爱分享网 1 下载安装包18G 迅雷磁力链 magnet
  • 前端之浅谈浏览器的垃圾回收机制和内存泄露

    前端之浅谈浏览器的垃圾回收机制和内存泄露 龙波帝国 博客园
  • 安装eclipse启动时报错

    1 在安装eclipse后 点击exe文件时 提示出现错误 记录在log文件中 因为log文件就是日志文件 可以方便我们排查错误 打开log文件 可以看到文件记录了每次出错的时间和错误栈信息 最新一次错误是 ENTRY org eclips
  • ‘cudaThreadSynchronize’ is deprecated

    Problem src gemm c In function time gpu src gemm c 232 9 warning cudaThreadSynchronize is deprecated Wdeprecated declara
  • C++程序中调用exe文件的一种方法

    我们在开发项目时 通常需要通过一个程序调用另一个程序 在这里介绍一中在C 程序中调用exe文件的方法 使用ShellExcecuteEx函数 使用ShellExcecuteEx相对于其他的调用exe的方法 例如 使用system函数 使用e
  • 区块链是生命体、经济体。未来的区块链世界离不开自己的价值尺度建设

    想知道更多区块链技术知识 请百度 链客区块链技术问答社区 链客 有问必答 公有链和联盟链的本质不同 区块链受到大家广泛关注应该是2015年10月 那时候万向在上海搞了一场区块链国际峰会 因为万向在整个金融界比较有影响力 加上 经济学人 在1
  • 如何删除在System中打开的iso文件

    目录 问题 解决方法 弹出DVD驱动器 删除iso文件 问题 在打开iso文件后 我的电脑中突然出现了一个DVD驱动器 如图1 而且原来的iso文件也无法删除 会提示文件在System中打开 如图2 图一 图二 解决方法 弹出DVD驱动器
  • 使用ffmpeg 将MP4格式 或其他格式转为谷歌浏览器可以播放的MP4文件

    场景 在网页上传任意视频格式的文件后 调用系统的ffmpeg 命令对其格式 转化后 发现谷歌浏览器压根无法播放 原因 视频不光区分格式 同一格式还区分编码 对于扩展名相同的视频文件它们的视频的编码可能是不一样的 mp4格式的视频就有3种编码
  • 【bnlearn in Python】Python下载bnlearn包的一些问题

    贝叶斯网络小萌新 请大家多多指教多多关注 文章目录 bnlearn document 下载超时问题 下载指令 证明下载成功 bnlearn document bnlearn包的指南文件见链接 bnlearn document 下载超时问题
  • kmp(看毛片)算法

    别人的两篇博客 传送门1 传送门2 摘录 其中T为主串 P为模式串 其实就是在T中找P 其中next数组存的是 部分匹配值 部分匹配值 就是 前缀 和 后缀 的最长的共有元素的长度 以 ABCDABD 为例 A 的前缀和后缀都为空集 共有元
  • 如何安装使用IP广播?

    步骤一 连接设备到同个局域网 设备连接网络 所有的设备与服务器处于同个局域网内 测试时放在同个交换机内 步骤二 在服务器上安装广播软件 再服务器上安装 数字网络广播系统软件 运行目录下的 Setup exe 文件 一直下一步直到完成 再服务
  • TortoiseSVN使用方法

    安装和配置 TortoiseSVN的下载地址为 http tortoisesvn net downloads html 有32位和64位的版本 一定要根据自己的操作系统下载对应的版本 最好安装一个简体中文的Language packs 可以
  • C++opencv进行图像处理(三)图像的基本操作

    1 图像像素的加法 主要包含了图像的像素加法 当像素增加 会使得图像变亮 当像素减少会使得图像变暗 除法操作会变暗 结果如下所示 左边是原图 右边是像素相加后的 在前面的代码模块中增加的代码为 void QuickDemo pixel op
  • STM32学习笔记—独立看门狗

    1 独立看门狗的介绍 2 独立看门狗的使用 3 代码段 1 独立看门狗的介绍 独立看门狗利用系统内部的低速时钟提供机械周期 这个低速时钟与系统的工作时钟不是一个时钟 所以看门狗的运行和系统的运行是互不干扰的 独立看门狗由内部专门的 40Kh
  • 计算机视觉---常见的颜色空间

    RGB 最常见的面向硬件设备的彩色模型 它是人的视觉系统密切相连的模型 根据人眼结构 所有的颜色都可以看做是3种基本颜色 红r 绿g 蓝b的不同比例的组合 HSV HSV颜色空间是孟塞尔彩色空间的简化形式 是一种基于感知的颜色模型 它将彩色
  • ShardingSphere水平、垂直分库、分表和公共表

    目录 一 ShardingSphere简介 二 ShardingSphere 分库分表 1 垂直拆分 1 垂直分库 2 垂直分表 2 水平拆分 1 水平分库 2 水平分表 三 水平分库操作 1 创建数据库和表 2 配置分片的规则 3 测试类
  • Java内存分配介绍

    Java的内存分配主要有三个位置 方法区 就是字节文件 存储未运行的代码 栈内存 当方法运行的时候 则在栈内存中存储 堆内存 当方法新生成对象的时候 或者新产生出局的时候将在堆内存中存储 方法区 字节文件加载时进入的内存 存储的就是编写成功
  • 常用服务器指令

    查看docker 容器占用进程 docker top 容器id 容器名 查看进程占用内存 top p PID 查看服务器所有进程 pid ef 查看内存 free 查看占用CUP最多 ps aux sort k4nr head n 10 查
  • 【Mariadb数据库用户及权限管理】

    一 用户管理 1 创建用户 方法一 直接创建用户 create user 用户名 来源 identified by 密码 来源地址 localhost 本机 192 168 150 网段 所有 方法二 在授权同时就创建用户 grant 权限
  • VTK笔记-图形相关-判断空间上的点是否在图元内-vtkSelectEnclosedPoints

    判断空间上的点是否在几何图元内 使用vtkSelectEnclosedPoints类 vtkSelectEnclosedPoints vtkSelectEnclosedPoints类可以判断标记点是否在封闭表面内 vtkSelectEncl