VTK_Learning_三角网格体积、表面积、测地距离、包围盒

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;
}

 

4.三维图像的包围盒 

 包围盒是指能够包围模型的最小立方体,常常用于模型的碰撞测量中。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;
}

其输出结果如下图所示:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值