VTK修炼之道46:图形基本操作进阶_三角网格体积、表面积、测地距离、包围盒

本文主要是介绍VTK修炼之道46:图形基本操作进阶_三角网格体积、表面积、测地距离、包围盒,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.基本图形操作意义

图形处理,比如图形平滑、多分辨率分析、特征提取等都离不开一些基本的图形操作。掌握这些基本的图形操作有助于理解和深入学习图形处理和分析方法。
VTK中提供了多种图形的基本操作,其中最简单的是点的欧氏距离计算,可以使用vtkMath进行计算,也可以直接计算向量的模。一些图元类提供了许多可以方便使用的静态函数,如
vtkLine提供了点与线间的距离计算;
vtkTriangle提供了面积、外接圆、法向量的计算,点与三角形位置关系判断等;
vtkTetra中实现了四面体体积,重心计算等。
有了这些函数,可以实现很多其他功能,如计算一个三角网格模型的表面积,只需要遍历每个三角形单元并计算其面积即可。
另外,还有一个办法是vtkMassProperties。这个类可以实现三角网格的表面积和体积计算,但是要求网格必须是封闭的三角形网格数据。网格的封闭性计算在后面会有更加详细的讨论。对于非三角形网格,需要先将网格转换为三角形网格。vtkTriangleFilter可以实现多边形网格数据向三角形网格数据转换。

2.三角网格模型面积、体积计算

利用vtkMassProperties计算三角网格模型面积、体积代码如下:
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL);
VTK_MODULE_INIT(vtkInteractionStyle);#include <vtkSmartPointer.h>
#include <vtkCubeSource.h>
#include <vtkTriangleFilter.h> //其他网格类型转换成三角网格类型
#include <vtkMassProperties.h> //计算三角网格的基本属性 面积。体积等
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkProperty.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>int main()
{vtkSmartPointer<vtkCubeSource> cubeSource =vtkSmartPointer<vtkCubeSource>::New(); //vtkPolyData类型数据cubeSource->Update();vtkSmartPointer<vtkTriangleFilter> triFilter =vtkSmartPointer<vtkTriangleFilter>::New();triFilter->SetInputData(cubeSource->GetOutput());triFilter->Update();vtkSmartPointer<vtkMassProperties> massProp =vtkSmartPointer<vtkMassProperties>::New();massProp->SetInputData(triFilter->GetOutput());float Volume = massProp->GetVolume();float SurfaceArea = massProp->GetSurfaceArea();float maxArea = massProp->GetMaxCellArea();float minArea = massProp->GetMinCellArea();std::cout << "the Volume   : " << Volume << std::endl;std::cout << "Surface Area : " << SurfaceArea << std::endl;std::cout << "MaxAreaofCell: " << maxArea << std::endl;std::cout << "MinAreaofCell: " << minArea << std::endl;///vtkSmartPointer<vtkPolyDataMapper> mapper =vtkSmartPointer<vtkPolyDataMapper>::New();mapper->SetInputData(triFilter->GetOutput());vtkSmartPointer<vtkActor> actor =vtkSmartPointer<vtkActor>::New();actor->SetMapper(mapper);actor->GetProperty()->SetColor(0, 0, 1);actor->GetProperty()->SetEdgeColor(1, 0, 0);actor->GetProperty()->SetEdgeVisibility(1);vtkSmartPointer<vtkRenderer> render =vtkSmartPointer<vtkRenderer>::New();render->AddActor(actor);render->SetBackground(0, 0, 0);vtkSmartPointer<vtkRenderWindow> rw =vtkSmartPointer<vtkRenderWindow>::New();rw->AddRenderer(render);rw->SetSize(480, 420);rw->SetWindowName("Calculating Area and Volume of Triangle grid");vtkSmartPointer<vtkRenderWindowInteractor> rwi =vtkSmartPointer<vtkRenderWindowInteractor>::New();rwi->SetRenderWindow(rw);rwi->Initialize();rwi->Start();return 0;
}
其输出结果为:

3.三维网格测地距离

对于三维网格模型来讲,测地距离也是一种重要的距离度量。与欧氏距离不同,一个三维模型上的亮点测地距离是指沿着模型表面两者之间的最短距离。测地距离通常采用Dijkstra算法类近似求解。VTK中的vtkDijkstraGraphGeodesicPath类就可以实现测地距离的求解。该类的使用如下例所示:
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL);
VTK_MODULE_INIT(vtkInteractionStyle); #include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkDijkstraGraphGeodesicPath.h>
#include <vtkProperty.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>int main()
{vtkSmartPointer<vtkSphereSource> sphereSource =vtkSmartPointer<vtkSphereSource>::New();sphereSource->Update();vtkSmartPointer<vtkDijkstraGraphGeodesicPath> dijstra =vtkSmartPointer<vtkDijkstraGraphGeodesicPath>::New();dijstra->SetInputData(sphereSource->GetOutput());dijstra->SetStartVertex(0);dijstra->SetEndVertex(10);dijstra->Update();///vtkSmartPointer<vtkPolyDataMapper> mapper =vtkSmartPointer<vtkPolyDataMapper>::New();mapper->SetInputData(sphereSource->GetOutput());vtkSmartPointer<vtkPolyDataMapper> pathMapper =vtkSmartPointer<vtkPolyDataMapper>::New();pathMapper->SetInputData(dijstra->GetOutput());vtkSmartPointer<vtkActor> actor =vtkSmartPointer<vtkActor>::New();actor->SetMapper(mapper);vtkSmartPointer<vtkActor> pathActor =vtkSmartPointer<vtkActor>::New();pathActor->SetMapper(pathMapper);pathActor->GetProperty()->SetColor(1, 0, 0);pathActor->GetProperty()->SetLineWidth(5);vtkSmartPointer<vtkRenderer> renderer =vtkSmartPointer<vtkRenderer>::New();renderer->AddActor(actor);renderer->AddActor(pathActor);renderer->SetBackground(0, 0, 0);vtkSmartPointer<vtkRenderWindow> rw =vtkSmartPointer<vtkRenderWindow>::New();rw->AddRenderer(renderer);rw->SetSize(640, 480);rw->SetWindowName("Calculating Geodesic Path");vtkSmartPointer<vtkRenderWindowInteractor> rwi =vtkSmartPointer<vtkRenderWindowInteractor>::New();rwi->SetRenderWindow(rw);rwi->Initialize();rwi->Start();return 0;
}
在这个例子中,我们定义了一个球形。计算测地距离时,必须指定球面两个点的索引号。SetStartVertex()设置开始点;SetEndVertex()设置结束点;计算完毕后,通过GetOutPut()函数可以得到一个vtkPolyData数据,即最短路径数据,其实质为折线段集合。最终结果,如下图所示:

3.三维图像的包围盒

包围盒是指能够包围模型的最小立方体,常常用于模型的碰撞测量中。vtkPolyData中定义了函数GetBounds()来获取包围盒的参数。即三个坐标轴方向上的最大、最小值。仅仅获取这些参数并不直观,有时候还需要显示包围盒。vtkOutlineFilter则提供了一个方便的方法来生成包围盒,其输入为一个vtkPolyData莫形数据,输出同样为一个vtkPolyData类型数据,因此非常容易进行可视化显示。
实例的参考代码如下所示:
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL);
VTK_MODULE_INIT(vtkInteractionStyle);#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkProperty.h>
#include <vtkOutlineFilter.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>int main()
{vtkSmartPointer<vtkSphereSource> sphereSource =vtkSmartPointer<vtkSphereSource>::New();sphereSource->SetCenter(0.0, 0.0, 0.0);sphereSource->SetRadius(5.0);sphereSource->Update();vtkPolyData* sphere = sphereSource->GetOutput();vtkSmartPointer<vtkOutlineFilter> outline =vtkSmartPointer<vtkOutlineFilter>::New();outline->SetInputData(sphere);outline->Update();//算法执行完毕,必须更新!!!vtkSmartPointer<vtkPolyDataMapper> mapper =vtkSmartPointer<vtkPolyDataMapper>::New();mapper->SetInputData(sphere);vtkSmartPointer<vtkPolyDataMapper> outlineMapper =vtkSmartPointer<vtkPolyDataMapper>::New();outlineMapper->SetInputData(outline->GetOutput());vtkSmartPointer<vtkActor> actor =vtkSmartPointer<vtkActor>::New();actor->SetMapper(mapper);vtkSmartPointer<vtkActor> outlineActor =vtkSmartPointer<vtkActor>::New();outlineActor->SetMapper(outlineMapper);outlineActor->GetProperty()->SetColor(0, 1, 0);outlineActor->GetProperty()->SetLineWidth(3);vtkSmartPointer<vtkRenderer> renderer =vtkSmartPointer<vtkRenderer>::New();renderer->AddActor(actor);renderer->AddActor(outlineActor);renderer->SetBackground(0, 0, 0);vtkSmartPointer<vtkRenderWindow> rw =vtkSmartPointer<vtkRenderWindow>::New();rw->AddRenderer(renderer);rw->SetSize(640, 480);;rw->SetWindowName("PolyData Bounding Box");rw->Render();vtkSmartPointer<vtkRenderWindowInteractor> rwi =vtkSmartPointer<vtkRenderWindowInteractor>::New();rwi->SetRenderWindow(rw);rwi->Start();return 0;
}
其输出结果如下图所示:

4.参看资料

1.《C++ primer》
2.《The VTK User’s Guide – 11thEdition》
3.  张晓东, 罗火灵. VTK图形图像开发进阶[M]. 机械工业出版社, 2015.

这篇关于VTK修炼之道46:图形基本操作进阶_三角网格体积、表面积、测地距离、包围盒的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/445282

相关文章

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

[MySQL表的增删改查-进阶]

🌈个人主页:努力学编程’ ⛅个人推荐: c语言从初阶到进阶 JavaEE详解 数据结构 ⚡学好数据结构,刷题刻不容缓:点击一起刷题 🌙心灵鸡汤:总有人要赢,为什么不能是我呢 💻💻💻数据库约束 🔭🔭🔭约束类型 not null: 指示某列不能存储 NULL 值unique: 保证某列的每行必须有唯一的值default: 规定没有给列赋值时的默认值.primary key:

【Linux 从基础到进阶】Ansible自动化运维工具使用

Ansible自动化运维工具使用 Ansible 是一款开源的自动化运维工具,采用无代理架构(agentless),基于 SSH 连接进行管理,具有简单易用、灵活强大、可扩展性高等特点。它广泛用于服务器管理、应用部署、配置管理等任务。本文将介绍 Ansible 的安装、基本使用方法及一些实际运维场景中的应用,旨在帮助运维人员快速上手并熟练运用 Ansible。 1. Ansible的核心概念

Flutter 进阶:绘制加载动画

绘制加载动画:由小圆组成的大圆 1. 定义 LoadingScreen 类2. 实现 _LoadingScreenState 类3. 定义 LoadingPainter 类4. 总结 实现加载动画 我们需要定义两个类:LoadingScreen 和 LoadingPainter。LoadingScreen 负责控制动画的状态,而 LoadingPainter 则负责绘制动画。

从0到1,AI我来了- (7)AI应用-ComfyUI-II(进阶)

上篇comfyUI 入门 ,了解了TA是个啥,这篇,我们通过ComfyUI 及其相关Lora 模型,生成一些更惊艳的图片。这篇主要了解这些内容:         1、哪里获取模型?         2、实践如何画一个美女?         3、附录:               1)相关SD(稳定扩散模型的组成部分)               2)模型放置目录(重要)

java学习,进阶,提升

http://how2j.cn/k/hutool/hutool-brief/1930.html?p=73689

【408DS算法题】039进阶-判断图中路径是否存在

Index 题目分析实现总结 题目 对于给定的图G,设计函数实现判断G中是否含有从start结点到stop结点的路径。 分析实现 对于图的路径的存在性判断,有两种做法:(本文的实现均基于邻接矩阵存储方式的图) 1.图的BFS BFS的思路相对比较直观——从起始结点出发进行层次遍历,遍历过程中遇到结点i就表示存在路径start->i,故只需判断每个结点i是否就是stop

Python中的属性装饰器:解锁更优雅的编程之道

引言 在Python的世界里,装饰器是一个强大的工具,它允许我们以一种非侵入性的方式修改函数或方法的行为。而当我们谈论“属性装饰器”时,则是在探讨如何使用装饰器来增强类中属性的功能。这不仅让我们的代码更加简洁、易读,同时也提供了强大的功能扩展能力。本文将带你深入了解属性装饰器的核心概念,并通过一系列实例展示其在不同场景下的应用,从基础到进阶,再到实际项目的实战经验分享,帮助你解锁Python编程