VTK:图sing基本操作进阶——三角网络体积、表面积、测地距离、包围盒
时间:2022-10-28 19:00:00
1.基本图形操作的意义
图形处理,如图形平滑、多分辨率分析、特征 提取与一些基本的图形操作密不可分。掌握这些基本的图形操作有助于理解和深入学习图形处理和分析方法。
VTK它提供了各种图形的基本操作,其中最简单的是点的欧洲距离计算,可以使用VTKMath也可以直接计算向量模。一些图元类提供了许多静态函数,可以方便地使用,
vtkLine提供点与线之间的距离计算;
vtkTriangle提供面积、外圆、法向量计算、点与三角形位置关系判断等;
vtkTetra中实现了四面体积,重心计算等。
有了这些函数,就可以实现许多其他功能的函数,比如计算一个三角形网格模型的面积,只需要通过每个三角形单元来计算它的面积。
另外,还有种方法是vtkMassProperties。这种类型可以计算三角形网格的表面积和体积,但网格必须是封闭的三角形网格数据。稍后将详细讨论网格的封闭计算。对于非三角形网格,需要将网格转换为三角形网格。
vtkTriangleFiler可以实现多变形网格数据向三角形网格数据转换。
2.计算三角网格模型面积和体积(类:vtkMassProperties)
#include VTK_MODULE_INIT(vtkRenderingOpenGL2); VTK_MODULE_INIT(vtkInteractionStyle); #include #include #include ///其他网格类型转换为三角网格类型 #include ///计算三角网格的基本属性 面积、体积等 #include #include #include #include #include #include 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类就可以实现测地距离求解。
下面的例子中,我们定义了一个球形。计算测地距离时,必须指定两个点的索引号。
SetStartVertex()设置开始点;SetEndVertex()设置结束点;计算完毕后,通过GetOutPut()函数可以得到一个vtkPolyData数据,即最短路径数据,其实质为折线段集合。
代码;
#include
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);
#include
#include
#include
#include
#include
#include
#include
#include
#include
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;
}
3.三维图像的包围盒
包围盒是指能够包围模型的最小立方体,常常用于模型碰撞测量中。VTKPolyData中定义函数GetBounds()来获取包围盒参数。即三个坐标方向上的最大、最小值。仅仅获取这些参数并不直观,有时候还需要显示包围盒。VTKPolyData则提供一个方便的方法来生成包围盒,其输入为一个VTKPolyData模型数据,输出同样为一个vtkPolyData类型数据,因此非常容易进行可视化显示。
代码
#include
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
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;
}