位移图主要描绘矢量点沿着与其所在表面垂直正交方向的运动,是一种可视化矢量数据的方法,广泛应用于用位移或应变矢量场描述物体运动的场合,如有限元分析位移、应力场的描述,经常采用这种方式,用位移图描述矢量数据在其表面上的运动形态时,常把矢量数据转化成标量数据,转换的方式采用矢量点的运动方向和表面的法向量两个矢量点乘,得到矢量点的标量值,如果标量值为正,表示为正位移(矢量的运动方向和法向量方向一致),如果为负,表示为负位移(矢量点的运动方向和法向量的方向相反),转化为标量的方法如下图所示:
图中矢量V表示矢量点的运动方向,N表示矢量点在表面的法向量。
下面给出位移图的示例程序。
#include "stdafx.h"
#include <vtkSmartPointer.h>
#include <vtkVolume16Reader.h>
#include <vtkMarchingCubes.h>
#include <vtkVectorNorm.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include "vtkCamera.h"
#include "vtkPolyData.h"
#include "vtkPolyDataMapper.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderer.h"
#include <vtkPolyDataReader.h>
#include <vtkPolyDataNormals.h>
#include <vtkWarpVector.h>
#include <vtkVectorDot.h>
#include <vtkProperty.h>
#include <vtkOutlineFilter.h>
#include <vtkLookupTable.h>
int _tmain(int argc, _TCHAR* argv[])
{
int i;
vtkSmartPointer<vtkPolyDataReader>pPolyRead=vtkPolyDataReader::New();
/读取多边形数据
pPolyRead->SetFileName("plate.vtk");
/提取数据文件中的mode8这部分矢量数据
pPolyRead->SetVectorsName("mode8");
/使用矢量数据弯曲几何体
vtkSmartPointer<vtkWarpVector>pWarpVec=vtkWarpVector::New();
/设置矢量数据缩放的比例
pWarpVec->SetScaleFactor(0.5);
pWarpVec->SetInput(pPolyRead->GetOutput());
/生成多边形数据的法线
vtkSmartPointer<vtkPolyDataNormals>pNormal=vtkPolyDataNormals::New();
pNormal->SetInput(pWarpVec->GetOutput());
/点的矢量和其法线点乘,生成点的标量值
vtkSmartPointer<vtkVectorDot>pVecDot=vtkVectorDot::New();
/pVecDot->SetInput(pNormal->GetOutput());
pVecDot->SetInputConnection(pNormal->GetOutputPort());
/创建颜色表
vtkSmartPointer<vtkLookupTable>pColorTable=vtkLookupTable::New();
pColorTable->SetNumberOfColors(256);
pColorTable->Build();
for(i=0;i<128;i++){
pColorTable->SetTableValue(i,(128.0-i)/128.0,(128.0-i)/128.0,(128.0-i)/128.0);
}
for(i=128;i<256;i++){
pColorTable->SetTableValue(i,(i-128.0)/128.0,(i-128.0)/128.0,(i-128.0)/128.0);
}
/创建映射器
vtkSmartPointer<vtkPolyDataMapper>pMapper=vtkPolyDataMapper::New();
/pMapper->SetInput((vtkPolyData *)pWarpVec->GetOutput());
pMapper->SetInputConnection(pVecDot->GetOutputPort());
pMapper->ScalarVisibilityOn();
pMapper->SetLookupTable(pColorTable);
pMapper->SetScalarRange(-1,1);//Rang[0],Rang[1]);
vtkSmartPointer<vtkActor>pActor = vtkActor::New();
pActor->SetMapper(pMapper);
/pActor->GetProperty()->SetColor(1.0,0.0,0.0);
/绘制没有发生变形以前的梁的几何形状
/创建多边形数据的外轮廓线
vtkSmartPointer<vtkOutlineFilter>pOutLine=vtkOutlineFilter::New();
pOutLine->SetInput(pPolyRead->GetOutput());
vtkSmartPointer<vtkPolyDataMapper>pOutlineMapper=vtkPolyDataMapper::New();
pOutlineMapper->SetInput((vtkPolyData *)pOutLine->GetOutput());
vtkSmartPointer<vtkActor>pOutlineActor=vtkActor::New();
pOutlineActor->SetMapper(pOutlineMapper);
pOutlineActor->GetProperty()->SetColor(0.0,0.0,1.0);
pOutlineActor->GetProperty()->SetLineWidth(2.0);
/绘制
vtkSmartPointer<vtkRenderer>renderer = vtkRenderer::New();
vtkSmartPointer<vtkRenderWindow>renWin = vtkRenderWindow::New();
renWin->AddRenderer(renderer);
vtkSmartPointer<vtkRenderWindowInteractor>iren = vtkRenderWindowInteractor::New();
iren->SetRenderWindow(renWin);
renderer->AddActor(pActor);
renderer->AddActor(pOutlineActor);
renderer->ResetCamera();
renderer->SetBackground(1,1,1);
renWin->SetSize(300,300);
renWin->Render();
iren->Start();
return 0;
}
示例程序用vtkVectorDot类计算矢量点的标量值,并且设定了一个颜色映射表,用亮度表示位移变化比较大的区域,黑暗的地方表示位移变化小的区域,和几何体变形相比,位移图最大的特点是将矢量数据转化成标量数据,然后用颜色映射的方法表示位移的状态,本示例程序将几何体变形和位移图叠加,可以直观的进行对比,程序运行结果如图所示: