VTK教程之九 可视化基础算法-二维…

二维轮廓线(等值线)提取属于标量可视化技术范围,常用于提取一个研究区域的轮廓边界,如在气象中应用中,常根据气象卫星或数值模拟的结果,按照每个地理位置点确定的属性值,分析区域内的降雨情况,提取不同降雨量的区域边界(如大雨、中雨、小雨的区域边界),在有限元分析中,常用于提取位移等值线等,在VTK中轮廓线提取功能主要面对的是规则网格数据集,对于非规则网格数据,必须要进行插值计算,生成规则网格数据集,由于规则网格数据其构成单元为正方形或长方形,所以提取轮廓线常采用移动四边形法(Marching Squares),该方法为移动立方体算法(Marching Cubes)的二维表达,因为本文是以实用性为主,所以对这些算法的理论不加以详细介绍,有关该方法的详细信息请参考《三维数据场可视化》(唐圣泽等著)这本书,本文从实用性的角度,对该方法做一个说明,该方法的主要核心是:

1、  定义规则网格数据顶点的属性值

2、  确定提取区域的属性值

3、  用提取区域的属性值和每个网格数据的每个单元进行比对,确定其是否在该单元内,如果在该单元内,要用插值的方法确定其和该单元边界的交点,然后继续比对下一个单元,如果不在该单元内,继续比对下一个单元。

4、  将各个单元的交点相连成线,即为边界区域。

下图给出了一个比对的示意:



 

在该示意图中,提取属性值为5的边界区域,假设从左到从上到下依次为单元编号,图中共有16个单元,构成第一个单元4个顶点按逆时针排列的属性值分别为0、1、3、1,均小于5,则该单元没有要提取的边界点,第一个单元顶点按逆时针排列的顺序为1、3、6、1,在3、6边及6、1边上分别有交点,计算出交点位置,依次对比各个单元,最终得到提取区域的边界,如,图中实线所画的闭合曲线就是提取的边界。

下面,以这个示意图数据为例,说明如何用VTK提供的功能提取轮廓线,以网格中心点为坐标原点,网格间距假设为一个单位,可确定各个顶点的坐标,示例代码如下:

#include "stdafx.h"

#include "vtkActor.h"

#include "vtkCamera.h"

#include "vtkCellArray.h"

#include "vtkFloatArray.h"

#include "vtkPointData.h"

#include "vtkPoints.h"

#include "vtkPolyData.h"

#include "vtkPolyDataMapper.h"

#include "vtkRenderWindow.h"

#include "vtkRenderWindowInteractor.h"

#include "vtkRenderer.h"

#include <vtkLookupTable.h>

#include <vtkContourFilter.h>

#include <vtkProperty.h>

int _tmain(int argc, _TCHAR* argv[])

{

    int i;

   /定义网格的顶点坐标

    vtkPoints *points = vtkPoints::New();

   /第1行5个点

    points->InsertNextPoint(-2.0,2.0,0.0);

    points->InsertNextPoint(-1.0,2.0,0.0);

    points->InsertNextPoint(0.0,2.0,0.0);

    points->InsertNextPoint(1.0,2.0,0.0);

    points->InsertNextPoint(2.0,2.0,0.0);

   /第2行5个点

    points->InsertNextPoint(-2.0,1.0,0.0);

    points->InsertNextPoint(-1.0,1.0,0.0);

    points->InsertNextPoint(0.0,1.0,0.0);

    points->InsertNextPoint(1.0,1.0,0.0);

    points->InsertNextPoint(2.0,1.0,0.0);

   /第3行5个点

    points->InsertNextPoint(-2.0,0.0,0.0);

    points->InsertNextPoint(-1.0,0.0,0.0);

    points->InsertNextPoint(0.0,0.0,0.0);

    points->InsertNextPoint(1.0,0.0,0.0);

    points->InsertNextPoint(2.0,0.0,0.0);

   /第4行5个点

    points->InsertNextPoint(-2.0,-1.0,0.0);

    points->InsertNextPoint(-1.0,-1.0,0.0);

    points->InsertNextPoint(0.0,-1.0,0.0);

    points->InsertNextPoint(1.0,-1.0,0.0);

    points->InsertNextPoint(2.0,-1.0,0.0);

   /第5行5个点

    points->InsertNextPoint(-2.0,-2.0,0.0);

    points->InsertNextPoint(-1.0,-2.0,0.0);

    points->InsertNextPoint(0.0,-2.0,0.0);

    points->InsertNextPoint(1.0,-2.0,0.0);

    points->InsertNextPoint(2.0,-2.0,0.0);

   /定义单元,每个顶点建立一个四边形单元,共计个单元

    static vtkIdType pts[16][4]={{0,5,6,1}, {1,6,7,2}, {2,7,8,3},

    {3,8,9,4}, {5,10,11,6}, {6,11,12,7},{7,12,13,8},{8,13,14,9},

    {10,15,16,11},{11,16,17,12},{12,17,18,13},{13,18,19,14},

    {15,20,21,16},{16,21,22,17},{17,22,23,18},{18,23,24,19}};

   /创建对象

    vtkPolyData *pGrid=vtkPolyData::New();

    vtkCellArray *polys=vtkCellArray::New();

   /设定单元

    for(i=0;i<16;i++)polys->InsertNextCell(4,pts[i]);

   /设定每个顶点的标量值

   /存储标量值

    vtkFloatArray *scalars = vtkFloatArray::New();

   /第1行

    scalars->InsertTuple1(0,0);

    scalars->InsertTuple1(1,1);

    scalars->InsertTuple1(2,1);

    scalars->InsertTuple1(3,3);

    scalars->InsertTuple1(4,2);

   /第2行

    scalars->InsertTuple1(5,1);

    scalars->InsertTuple1(6,3);

    scalars->InsertTuple1(7,6);

    scalars->InsertTuple1(8,6);

    scalars->InsertTuple1(9,3);

   /第3行

    scalars->InsertTuple1(10,3);

    scalars->InsertTuple1(11,7);

    scalars->InsertTuple1(12,9);

    scalars->InsertTuple1(13,7);

    scalars->InsertTuple1(14,3);

   /第4行

    scalars->InsertTuple1(15,2);

    scalars->InsertTuple1(16,7);

    scalars->InsertTuple1(17,8);

    scalars->InsertTuple1(18,6);

    scalars->InsertTuple1(19,2);

   /第5行

    scalars->InsertTuple1(20,1);

    scalars->InsertTuple1(21,2);

    scalars->InsertTuple1(22,3);

    scalars->InsertTuple1(23,4);

    scalars->InsertTuple1(24,3);

   /创建多边形数据

    pGrid->SetPoints(points);

   /设定单元类型为多边形

    pGrid->SetPolys(polys);

   /设定每个顶点的标量值

    pGrid->GetPointData()->SetScalars(scalars);

    points->Delete();

    polys->Delete();

    scalars->Delete();

   /定义颜色映射表

    vtkLookupTable *pColorTable=vtkLookupTable::New();

   /设置颜色表中的颜色

    pColorTable->SetHueRange(0.667,0.887);

    pColorTable->SetNumberOfColors(255);

    pColorTable->Build();

   /数据映射,使用默认颜色映射表

    vtkPolyDataMapper *cubeMapper = vtkPolyDataMapper::New();

    cubeMapper->SetInput(pGrid);

   /设置标量值范围

cubeMapper->SetScalarRange(0,9);

    cubeMapper->SetLookupTable(pColorTable);

    vtkActor *cubeActor = vtkActor::New();

    cubeActor->SetMapper(cubeMapper);

   /提取轮廓线

    vtkContourFilter *pContourFilter=vtkContourFilter::New();

   /设置提取的标量值

    pContourFilter->SetValue(0,5.0);

    pContourFilter->SetInput(pGrid);

    vtkPolyDataMapper *pContouMapper=vtkPolyDataMapper::New();

    pContouMapper->SetInput((vtkPolyData *)pContourFilter->GetOutput());

   /禁用属性数据绘制颜色

    pContouMapper->ScalarVisibilityOff();

    vtkActor *pContoActor = vtkActor::New();

    pContoActor->SetMapper(pContouMapper);

    pContoActor->GetProperty()->SetColor(1.0,1.0,0.0);

    pContoActor->GetProperty()->SetLineWidth(10.0);

   /绘制

    vtkCamera *camera = vtkCamera::New();

    camera->SetPosition(1,1,1);

    camera->SetFocalPoint(0,0,0);

    vtkRenderer *renderer = vtkRenderer::New();

    vtkRenderWindow *renWin = vtkRenderWindow::New();

    renWin->AddRenderer(renderer);

    vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();

    iren->SetRenderWindow(renWin);

    renderer->AddActor(cubeActor);

    renderer->AddActor(pContoActor);

    renderer->SetActiveCamera(camera);

    renderer->ResetCamera();

    renderer->SetBackground(1,1,1);

    renWin->SetSize(300,300);

    renWin->Render();

    iren->Start();

   /删除对象

    pGrid->Delete();

    cubeMapper->Delete();

    cubeActor->Delete();

    camera->Delete();

    renderer->Delete();

    renWin->Delete();

    iren->Delete();

    pColorTable->Delete();

    return 0;

}

在VTK中vtkContourFilter过滤器类实现了轮廓线提取功能,该过滤器接收多边形数据集作为输入,并将生成的多边形数据集作为输出,程序运行后的结果如下:

 


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值