VTK修炼之道47:图形基本操作进阶_法向量计算
生活随笔
收集整理的這篇文章主要介紹了
VTK修炼之道47:图形基本操作进阶_法向量计算
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1.點法向量和單元法向量
三維平面的法向量是指垂直于該平面的三維向量。曲面在某點P處的法向量為垂直于該點切平面的向量。對于一個網格模型,其每一個點和單元都可以計算一個法向量,在三維計算機圖形學中法向量一個重要應用是光照和陰影計算。對于網格模型,模型是有一定數量的面片(單元)來逼近的,面片越多,則模型越精細;反之,則越粗糙。在計算網格模型的法向量時,單元法向量計算比較簡單,可以通過組成每個單元的任意兩條邊的叉乘向量并歸一化來表示。而,對于點的法向量,則是由所有使用該點的單元法向量的平均值來表示。 VTK中計算法向量的Filter是vtkPolyDataNormals()。該類針對單元為 三角形或者多邊形類型的vtkPolyData數據進行計算。由于法向量分為點法向量和單元法向量,可以通過函數SetComputeCellNormals()和SetComputePointNormals()來設置需要計算的法向量類型。 默認情況下計算點法向量,關閉單元法向量計算。 示例演示了一個vtkPolyData模型的點法向量和單位法向量的計算: #include <vtkAutoInit.h> VTK_MODULE_INIT(vtkRenderingOpenGL); VTK_MODULE_INIT(vtkInteractionStyle);#include <vtkSmartPointer.h> #include <vtkPolyDataReader.h> #include <vtkPolyDataNormals.h> //計算法向量 #include <vtkMaskPoints.h> #include <vtkArrowSource.h> #include <vtkGlyph3D.h> #include <vtkPointData.h> #include <vtkProperty.h> // #include <vtkPolyDataMapper.h> #include <vtkActor.h> #include <vtkRenderer.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h>int main() {vtkSmartPointer<vtkPolyDataReader> plyReader =vtkSmartPointer<vtkPolyDataReader>::New();plyReader->SetFileName("fran_cut.vtk");plyReader->Update();vtkSmartPointer<vtkPolyDataNormals> normFilter =vtkSmartPointer<vtkPolyDataNormals>::New();normFilter->SetInputData(plyReader->GetOutput());normFilter->SetComputePointNormals(1);//開啟點法向量計算normFilter->SetComputeCellNormals(0); //關閉單元法向量計算normFilter->SetAutoOrientNormals(1);normFilter->SetSplitting(0);normFilter->Update();vtkSmartPointer<vtkMaskPoints> mask =vtkSmartPointer<vtkMaskPoints>::New();mask->SetInputData(normFilter->GetOutput());mask->SetMaximumNumberOfPoints(300);mask->RandomModeOn();mask->Update();vtkSmartPointer<vtkArrowSource> arrow =vtkSmartPointer<vtkArrowSource>::New();arrow->Update(); //一定要更新 否則數據沒有添加進來,程序會報錯vtkSmartPointer<vtkGlyph3D> glyph =vtkSmartPointer<vtkGlyph3D>::New();glyph->SetInputData(mask->GetOutput());glyph->SetSourceData(arrow->GetOutput());//每一點用箭頭代替glyph->SetVectorModeToUseNormal();//設置向量顯示模式和法向量一致glyph->SetScaleFactor(0.01); //設置伸縮比例glyph->Update();vtkSmartPointer<vtkPolyDataMapper> mapper =vtkSmartPointer<vtkPolyDataMapper>::New();mapper->SetInputData(plyReader->GetOutput());vtkSmartPointer<vtkPolyDataMapper> normMapper =vtkSmartPointer<vtkPolyDataMapper>::New();normMapper->SetInputData(normFilter->GetOutput());vtkSmartPointer<vtkPolyDataMapper> glyphMapper =vtkSmartPointer<vtkPolyDataMapper>::New();glyphMapper->SetInputData(glyph->GetOutput());vtkSmartPointer<vtkActor> actor =vtkSmartPointer<vtkActor>::New();actor->SetMapper(mapper);vtkSmartPointer<vtkActor> normActor =vtkSmartPointer<vtkActor>::New();normActor->SetMapper(normMapper);vtkSmartPointer<vtkActor> glyphActor =vtkSmartPointer<vtkActor>::New();glyphActor->SetMapper(glyphMapper);glyphActor->GetProperty()->SetColor(1, 0, 0);double origView[4] = { 0, 0, 0.33, 1 };double normView[4] = { 0.33, 0, 0.66, 1 };double glyphView[4] = { 0.66, 0, 1, 1 };vtkSmartPointer<vtkRenderer> origRender =vtkSmartPointer<vtkRenderer>::New();origRender->SetViewport(origView);origRender->AddActor(actor);origRender->SetBackground(1, 0, 0);vtkSmartPointer<vtkRenderer> normRender =vtkSmartPointer<vtkRenderer>::New();normRender->SetViewport(normView);normRender->AddActor(normActor);normRender->SetBackground(0, 1, 0);vtkSmartPointer<vtkRenderer> glyphRender =vtkSmartPointer<vtkRenderer>::New();glyphRender->SetViewport(glyphView);glyphRender->AddActor(glyphActor);glyphRender->AddActor(normActor);glyphRender->SetBackground(0, 0, 1);vtkSmartPointer<vtkRenderWindow> rw =vtkSmartPointer<vtkRenderWindow>::New();rw->AddRenderer(origRender);rw->AddRenderer(normRender);rw->AddRenderer(glyphRender);rw->SetWindowName("Calculating Point Norm & Cell Norm");rw->SetSize(960, 320);rw->Render();vtkSmartPointer<vtkRenderWindowInteractor> rwi =vtkSmartPointer<vtkRenderWindowInteractor>::New();rwi->SetRenderWindow(rw);rwi->Initialize();rwi->Start();return 0; }輸出結果如下圖所示:在計算法向量時需要注意一個問題,即法向量的方向。因為對于同一個平面來講,可以有兩個方向完全相反的法向量。一般是根據單元的點的順序確定,采用右手定則來定義一個平面的法向量方向。因此計算平面方向量的時候,法向量的方向與單元的點的順序密切相關。必須保持單元的點順序一致,才會得到合理的法向量。當然,函數SetConsistency()可以設置自動調整模型的單元法向量。SetAutoOrientNormals()可以設置自動調整法線的方向。
2.關于類vtkGlyph3D
詳細描述:為每個輸入點拷貝相應方向和伸縮比例的輪廓幾何體vtkGlyph3d是一個過濾器,當拷貝幾何體到每個輸入點時,它起到濾波作用.glyph從過濾輸入源中以多邊形數據形式定義,glyph根據輸入的矢量和法向量來確定方向,根據伸縮數據和矢量大小來確定伸縮比例.當glyph較多時,可能通過對象源與其相應的定義信息來創建glyph表.glyph表可以通過伸縮值或矢量大小來索引相應的gpyph對象.
要使用vtkGlyph3D對象,我們首先需要提供一個輸入集和一個對象源來定義ghyph.然后決定是否對ghyph進行伸縮,以及怎樣對其進行伸縮,接下來決定是否對glyph設置方向,以及如何根據矢量及法向量來設置它,最終決定我們是用glyph表還是僅僅是單一的ghyph.如果使用了glyph表,我們還需要考慮相應的索引值.
vtkGlyph3D 實際上是一種符號化的算法工具,可以使用一個源(如球體)為輸入數據集的每一個點生成一個符號,并且可以設置符號的方向以及縮放比例,簡單點說就是對于你想關注的數據點添加符號標注,符號的樣式由自己指定。比如你有一個曲面數據,希望將曲面數據的每個點都用錐體標注出來并且錐體的方向表示該點的法向量方向,這個時候就可以使用vtkGlyph3D。
3.本例的注意事項與經驗談
注意算法執行之后,要注意及時更新,Update()一下!!!4.參看資料
1.《C++ primer》2.《The VTK User’s Guide – 11thEdition》
3. ?張曉東, 羅火靈. VTK圖形圖像開發進階[M]. 機械工業出版社, 2015.
總結
以上是生活随笔為你收集整理的VTK修炼之道47:图形基本操作进阶_法向量计算的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: VTK修炼之道46:图形基本操作进阶_三
- 下一篇: [视频]Google Chrome背后的