VTK 圖形基本操作進階_三角網格體積、表面積、測地距離、包圍盒


1.基本圖形操作意義

圖形處理,比如圖形平滑、多分辨率分析、特征提取等都離不開一些基本的圖形操作。掌握這些基本的圖形操作有助於理解和深入學習圖形處理和分析方法。
VTK中提供了多種圖形的基本操作,其中最簡單的是點的歐氏距離計算,可以使用vtkMath進行計算,也可以直接計算向量的模。一些圖元類提供了許多可以方便使用的靜態函數,如
vtkLine提供了點與線間的距離計算;
vtkTriangle提供了面積、外接圓、法向量的計算,點與三角形位置關系判斷等;
vtkTetra中實現了四面體體積,重心計算等。
有了這些函數,可以實現很多其他功能,如計算一個三角網格模型的表面積,只需要遍歷每個三角形單元並計算其面積即可。
另外,還有一個辦法是vtkMassProperties。這個類可以實現三角網格的表面積和體積計算,但是要求網格必須是封閉的三角形網格數據。網格的封閉性計算在后面會有更加詳細的討論。對於非三角形網格,需要先將網格轉換為三角形網格。vtkTriangleFilter可以實現多邊形網格數據向三角形網格數據轉換。

2.三角網格模型面積、體積計算

利用vtkMassProperties計算三角網格模型面積、體積代碼如下:
 1 #include <vtkAutoInit.h>
 2 VTK_MODULE_INIT(vtkRenderingOpenGL);  3 VTK_MODULE_INIT(vtkInteractionStyle);  4  
 5 #include <vtkSmartPointer.h>
 6 #include <vtkCubeSource.h>
 7 #include <vtkTriangleFilter.h> //其他網格類型轉換成三角網格類型
 8 #include <vtkMassProperties.h> //計算三角網格的基本屬性 面積。體積等
 9 #include <vtkPolyDataMapper.h>
10 #include <vtkActor.h>
11 #include <vtkProperty.h>
12 #include <vtkRenderer.h>
13 #include <vtkRenderWindow.h>
14 #include <vtkRenderWindowInteractor.h>
15  
16 int main() 17 { 18     vtkSmartPointer<vtkCubeSource> cubeSource =
19         vtkSmartPointer<vtkCubeSource>::New(); //vtkPolyData類型數據
20     cubeSource->Update(); 21  
22     vtkSmartPointer<vtkTriangleFilter> triFilter =
23         vtkSmartPointer<vtkTriangleFilter>::New(); 24     triFilter->SetInputData(cubeSource->GetOutput()); 25     triFilter->Update(); 26  
27     vtkSmartPointer<vtkMassProperties> massProp =
28         vtkSmartPointer<vtkMassProperties>::New(); 29     massProp->SetInputData(triFilter->GetOutput()); 30     float Volume = massProp->GetVolume(); 31     float SurfaceArea = massProp->GetSurfaceArea(); 32     float maxArea = massProp->GetMaxCellArea(); 33     float minArea = massProp->GetMinCellArea(); 34     std::cout << "the Volume : " << Volume << std::endl; 35     std::cout << "Surface Area : " << SurfaceArea << std::endl; 36     std::cout << "MaxAreaofCell: " << maxArea << std::endl; 37     std::cout << "MinAreaofCell: " << minArea << std::endl; 38     /// 39     vtkSmartPointer<vtkPolyDataMapper> mapper =
40         vtkSmartPointer<vtkPolyDataMapper>::New(); 41     mapper->SetInputData(triFilter->GetOutput()); 42  
43     vtkSmartPointer<vtkActor> actor =
44         vtkSmartPointer<vtkActor>::New(); 45     actor->SetMapper(mapper); 46     actor->GetProperty()->SetColor(0, 0, 1); 47     actor->GetProperty()->SetEdgeColor(1, 0, 0); 48     actor->GetProperty()->SetEdgeVisibility(1); 49  
50     vtkSmartPointer<vtkRenderer> render =
51         vtkSmartPointer<vtkRenderer>::New(); 52     render->AddActor(actor); 53     render->SetBackground(0, 0, 0); 54  
55     vtkSmartPointer<vtkRenderWindow> rw =
56         vtkSmartPointer<vtkRenderWindow>::New(); 57     rw->AddRenderer(render); 58     rw->SetSize(480, 420); 59     rw->SetWindowName("Calculating Area and Volume of Triangle grid"); 60  
61     vtkSmartPointer<vtkRenderWindowInteractor> rwi =
62         vtkSmartPointer<vtkRenderWindowInteractor>::New(); 63     rwi->SetRenderWindow(rw); 64     rwi->Initialize(); 65     rwi->Start(); 66  
67     return 0; 68 }
其輸出結果為:

3.三維網格測地距離

對於三維網格模型來講,測地距離也是一種重要的距離度量。與歐氏距離不同,一個三維模型上的亮點測地距離是指沿着模型表面兩者之間的最短距離。測地距離通常采用Dijkstra算法類近似求解。VTK中的vtkDijkstraGraphGeodesicPath類就可以實現測地距離的求解。該類的使用如下例所示:
 1 #include <vtkAutoInit.h>
 2 VTK_MODULE_INIT(vtkRenderingOpenGL);  3 VTK_MODULE_INIT(vtkInteractionStyle);  4  
 5 #include <vtkSmartPointer.h>
 6 #include <vtkSphereSource.h>
 7 #include <vtkDijkstraGraphGeodesicPath.h>
 8 #include <vtkProperty.h>
 9 #include <vtkPolyDataMapper.h>
10 #include <vtkActor.h>
11 #include <vtkRenderer.h>
12 #include <vtkRenderWindow.h>
13 #include <vtkRenderWindowInteractor.h>
14  
15 int main() 16 { 17     vtkSmartPointer<vtkSphereSource> sphereSource =
18         vtkSmartPointer<vtkSphereSource>::New(); 19     sphereSource->Update(); 20  
21     vtkSmartPointer<vtkDijkstraGraphGeodesicPath> dijstra =
22         vtkSmartPointer<vtkDijkstraGraphGeodesicPath>::New(); 23     dijstra->SetInputData(sphereSource->GetOutput()); 24     dijstra->SetStartVertex(0); 25     dijstra->SetEndVertex(10); 26     dijstra->Update(); 27     /// 28     vtkSmartPointer<vtkPolyDataMapper> mapper =
29         vtkSmartPointer<vtkPolyDataMapper>::New(); 30     mapper->SetInputData(sphereSource->GetOutput()); 31     vtkSmartPointer<vtkPolyDataMapper> pathMapper =
32         vtkSmartPointer<vtkPolyDataMapper>::New(); 33     pathMapper->SetInputData(dijstra->GetOutput()); 34  
35     vtkSmartPointer<vtkActor> actor =
36         vtkSmartPointer<vtkActor>::New(); 37     actor->SetMapper(mapper); 38     vtkSmartPointer<vtkActor> pathActor =
39         vtkSmartPointer<vtkActor>::New(); 40     pathActor->SetMapper(pathMapper); 41     pathActor->GetProperty()->SetColor(1, 0, 0); 42     pathActor->GetProperty()->SetLineWidth(5); 43  
44     vtkSmartPointer<vtkRenderer> renderer =
45         vtkSmartPointer<vtkRenderer>::New(); 46     renderer->AddActor(actor); 47     renderer->AddActor(pathActor); 48     renderer->SetBackground(0, 0, 0); 49  
50     vtkSmartPointer<vtkRenderWindow> rw =
51         vtkSmartPointer<vtkRenderWindow>::New(); 52     rw->AddRenderer(renderer); 53     rw->SetSize(640, 480); 54     rw->SetWindowName("Calculating Geodesic Path"); 55     
56     vtkSmartPointer<vtkRenderWindowInteractor> rwi =
57         vtkSmartPointer<vtkRenderWindowInteractor>::New(); 58     rwi->SetRenderWindow(rw); 59     rwi->Initialize(); 60     rwi->Start(); 61  
62     return 0; 63 }
在這個例子中,我們定義了一個球形。計算測地距離時,必須指定球面兩個點的索引號。SetStartVertex()設置開始點;SetEndVertex()設置結束點;計算完畢后,通過GetOutPut()函數可以得到一個vtkPolyData數據,即最短路徑數據,其實質為折線段集合。最終結果,如下圖所示:

3.三維圖像的包圍盒

包圍盒是指能夠包圍模型的最小立方體,常常用於模型的碰撞測量中。vtkPolyData中定義了函數GetBounds()來獲取包圍盒的參數。即三個坐標軸方向上的最大、最小值。僅僅獲取這些參數並不直觀,有時候還需要顯示包圍盒。vtkOutlineFilter則提供了一個方便的方法來生成包圍盒,其輸入為一個vtkPolyData莫形數據,輸出同樣為一個vtkPolyData類型數據,因此非常容易進行可視化顯示。
實例的參考代碼如下所示:
 1 #include <vtkAutoInit.h>
 2 VTK_MODULE_INIT(vtkRenderingOpenGL);  3 VTK_MODULE_INIT(vtkInteractionStyle);  4  
 5 #include <vtkSmartPointer.h>
 6 #include <vtkSphereSource.h>
 7 #include <vtkProperty.h>
 8 #include <vtkOutlineFilter.h>
 9 #include <vtkPolyData.h>
10 #include <vtkPolyDataMapper.h>
11 #include <vtkActor.h>
12 #include <vtkRenderer.h>
13 #include <vtkRenderWindow.h>
14 #include <vtkRenderWindowInteractor.h>
15  
16 int main() 17 { 18     vtkSmartPointer<vtkSphereSource> sphereSource =
19         vtkSmartPointer<vtkSphereSource>::New(); 20     sphereSource->SetCenter(0.0, 0.0, 0.0); 21     sphereSource->SetRadius(5.0); 22     sphereSource->Update(); 23  
24     vtkPolyData* sphere = sphereSource->GetOutput(); 25     vtkSmartPointer<vtkOutlineFilter> outline =
26         vtkSmartPointer<vtkOutlineFilter>::New(); 27     outline->SetInputData(sphere); 28     outline->Update();//算法執行完畢,必須更新!!!
29  
30     vtkSmartPointer<vtkPolyDataMapper> mapper =
31         vtkSmartPointer<vtkPolyDataMapper>::New(); 32     mapper->SetInputData(sphere); 33     vtkSmartPointer<vtkPolyDataMapper> outlineMapper =
34         vtkSmartPointer<vtkPolyDataMapper>::New(); 35     outlineMapper->SetInputData(outline->GetOutput()); 36  
37     vtkSmartPointer<vtkActor> actor =
38         vtkSmartPointer<vtkActor>::New(); 39     actor->SetMapper(mapper); 40     vtkSmartPointer<vtkActor> outlineActor =
41         vtkSmartPointer<vtkActor>::New(); 42     outlineActor->SetMapper(outlineMapper); 43     outlineActor->GetProperty()->SetColor(0, 1, 0); 44     outlineActor->GetProperty()->SetLineWidth(3); 45  
46     vtkSmartPointer<vtkRenderer> renderer =
47         vtkSmartPointer<vtkRenderer>::New(); 48     renderer->AddActor(actor); 49     renderer->AddActor(outlineActor); 50     renderer->SetBackground(0, 0, 0); 51  
52     vtkSmartPointer<vtkRenderWindow> rw =
53         vtkSmartPointer<vtkRenderWindow>::New(); 54     rw->AddRenderer(renderer); 55     rw->SetSize(640, 480);; 56     rw->SetWindowName("PolyData Bounding Box"); 57     rw->Render(); 58  
59     vtkSmartPointer<vtkRenderWindowInteractor> rwi =
60         vtkSmartPointer<vtkRenderWindowInteractor>::New(); 61     rwi->SetRenderWindow(rw); 62     rwi->Start(); 63     return 0; 64 }
其輸出結果如下圖所示:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM