VTK 的可视化方法:流线、流管、流面、流带

2024-05-03 09:52

本文主要是介绍VTK 的可视化方法:流线、流管、流面、流带,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

VTK 的可视化方法:流线、流管、流面、流带

  • VTK 的可视化方法:流线、流管、流面、流带
    • 三种相似的可视化方法
    • 流线生成使用的类
    • 实例:单一流线
    • 实例:流管
    • 实例:多条流线
    • 实例:流面
    • 实例:流带
    • 完整代码

VTK 的可视化方法:流线、流管、流面、流带

2维流线示例:

在这里插入图片描述

本文章主要讲解3维的流线、流管、流面、流带的构造方法。

三种相似的可视化方法

  1. 流线(Streamlines):每个点速度切线方向连成的线。
  2. 迹线(Pathlines):粒子实际的轨迹线。
  3. 脉线(Streaklines):连续时刻出发的粒子在某一时刻的连线。

流线生成使用的类

  • vtkRungeKutta4:四阶龙格库塔 (Runge-Kutta) 求解微分。
  • vtkStreamTracer:通过整合矢量场生成流线。

实例:单一流线

完整代码:

#include "VTKStreamline.h"#include <vtkConeSource.h>
#include <vtkMultiBlockPLOT3DReader.h>
#include <vtkDataSet.h>
#include <vtkMultiBlockDataSet.h>
#include <vtkRungeKutta4.h>
#include <vtkStreamTracer.h>
#include <vtkDataArray.h>
#include <vtkPointData.h>
#include <vtkShrinkPolyData.h>
#include <vtkStructuredGridGeometryFilter.h>
#include <vtkStructuredGridOutlineFilter.h>
#include <vtkContourFilter.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>VTKStreamline::VTKStreamline(QWidget* parent): QMainWindow(parent)
{ui.setupUi(this);_pVTKWidget = new QVTKOpenGLNativeWidget();this->setCentralWidget(_pVTKWidget);// this->showMaximized();// 1. generate data// vtkSmartPointer<vtkConeSource> cone = vtkSmartPointer<vtkConeSource>::New();// or, read data// vtkMultiBlockPLOT3DReader 是一个读取器对象,用于读取 PLOT3D 格式的文件并在输出时生成结构化网格vtkSmartPointer<vtkMultiBlockPLOT3DReader> plot3dReader = vtkSmartPointer<vtkMultiBlockPLOT3DReader>::New();plot3dReader->SetXYZFileName("combxyz.bin");plot3dReader->SetQFileName("combq.bin");plot3dReader->SetScalarFunctionNumber(100);plot3dReader->SetVectorFunctionNumber(202);qDebug() << plot3dReader->GetOutput()->GetNumberOfBlocks(); // 0// 反向更新管线plot3dReader->Update();qDebug() << plot3dReader->GetOutput()->GetNumberOfBlocks(); // 1vtkDataSet* plot3dOutput = (vtkDataSet*)(plot3dReader->GetOutput()->GetBlock(0));// 四阶龙格库塔 (Runge-Kutta) 求解微分vtkSmartPointer<vtkRungeKutta4> integ = vtkSmartPointer<vtkRungeKutta4>::New();// 通过整合矢量场生成流线vtkSmartPointer<vtkStreamTracer> streamer = vtkSmartPointer<vtkStreamTracer>::New();streamer->SetIntegrator(integ);streamer->SetInputData(plot3dOutput);streamer->SetStartPosition(15, 5, 32);streamer->SetMaximumPropagation(100);streamer->SetInitialIntegreationStep(0.1);streamer->SetIntegreationDirectionToBackward();// 2. filter// 产生结构化栅格边界的一个线轮廓vtkSmartPointer<vtkStructuredGridOutlineFilter> outline = vtkSmartPointer<vtkStructuredGridOutlineFilter>::New();outline->SetInputData(plot3dOutput);// 3. mappervtkSmartPointer<vtkPolyDataMapper> outlineMapper = vtkSmartPointer<vtkPolyDataMapper>::New();vtkSmartPointer<vtkPolyDataMapper> singleMapper = vtkSmartPointer<vtkPolyDataMapper>::New();singleMapper->SetScalarRange(plot3dOutput->GetPointData()->GetScalars()->GetRange());// 4. actorvtkSmartPointer<vtkActor> outlineActor = vtkSmartPointer<vtkActor>::New();vtkSmartPointer<vtkActor> singleActor = vtkSmartPointer<vtkActor>::New();// 5. renderervtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();renderer->SetBackground(0.3, 0.6, 0.3); // Background Color: Green// 6. connectoutlineMapper->SetInputConnection(outline->GetOutputPort());singleMapper->SetInputConnection(streamer->GetOutputPort());outlineActor->SetMapper(outlineMapper);singleActor->SetMapper(singleMapper);renderer->AddActor(outlineActor);renderer->AddActor(singleActor);this->_pVTKWidget->renderWindow()->AddRenderer(renderer);this->_pVTKWidget->renderWindow()->Render();
}VTKStreamline::~VTKStreamline()
{}

运行效果:

在这里插入图片描述

实例:流管

我们再加上一个过滤器,把流线变成流管:

	vtkSmartPointer<vtkTubeFilter> streamTube = vtkSmartPointer<vtkTubeFilter>::New();streamTube->SetInputConnection(streamer->GetOutputPort());streamTube->SetRadius(0.06);streamTube->SetNumberOfSides(12);

流管实际上是用一个圆柱面包裹住流线,流线依旧存在。这样的显示效果会更好一点:

在这里插入图片描述

实例:多条流线

在之前的代码中,新增:

	vtkSmartPointer<vtkLineSource> seeds = vtkSmartPointer<vtkLineSource>::New();// 设置线段的端点seeds->SetPoint1(15, -5, 32);seeds->SetPoint2(15, 5, 32);seeds->SetResolution(21);	vtkSmartPointer<vtkStreamTracer> streamer2 = vtkSmartPointer<vtkStreamTracer>::New();streamer2->SetIntegrator(integ);streamer2->SetInputData(plot3dOutput);// streamer2->SetStartPosition(15, 5, 32);streamer2->SetMaximumPropagation(100);streamer2->SetInitialIntegreationStep(0.1);streamer2->SetIntegreationDirectionToBackward();streamer2->SetSourceConnection(seeds->GetOutputPort());vtkSmartPointer<vtkPolyDataMapper> multipleMapper = vtkSmartPointer<vtkPolyDataMapper>::New();multipleMapper->SetScalarRange(plot3dOutput->GetPointData()->GetScalars()->GetRange());vtkSmartPointer<vtkActor> multipleActor = vtkSmartPointer<vtkActor>::New();multipleMapper->SetInputConnection(streamer2->GetOutputPort());multipleActor->SetMapper(multipleMapper);renderer->AddActor(multipleActor);

在这里插入图片描述

实例:流面

新增一个过滤器 vtkRuledSurfaceFilter,把多条流线合并成一个流面:

	vtkSmartPointer<vtkRuledSurfaceFilter> scalarSurface = vtkSmartPointer<vtkRuledSurfaceFilter>::New();scalarSurface->SetInputConnection(streamer2->GetOutputPort());// 设置生成方法scalarSurface->SetRuledModeToPointWalk();// multipleMapper->SetInputConnection(streamer2->GetOutputPort());multipleMapper->SetInputConnection(scalarSurface->GetOutputPort());

运行结果:

在这里插入图片描述

实例:流带

流带其实是按每条流线拓展而成的一条条带状的面,比起流面,更能便于展示走势。

我们只需要在前面的代码中新增一行代码:

	vtkSmartPointer<vtkRuledSurfaceFilter> scalarSurface = vtkSmartPointer<vtkRuledSurfaceFilter>::New();scalarSurface->SetInputConnection(streamer2->GetOutputPort());// 设置生成方法scalarSurface->SetRuledModeToPointWalk();scalarSurface->SetOnRatio(2); // 新增代码

运行结果:

在这里插入图片描述

完整代码

#include "VTKStreamline.h"#include <vtkConeSource.h>
#include <vtkLineSource.h>
#include <vtkMultiBlockPLOT3DReader.h>
#include <vtkDataSet.h>
#include <vtkMultiBlockDataSet.h>
#include <vtkRungeKutta4.h>
#include <vtkStreamTracer.h>
#include <vtkTubeFilter.h>
#include <vtkDataArray.h>
#include <vtkPointData.h>
#include <vtkShrinkPolyData.h>
#include <vtkStructuredGridGeometryFilter.h>
#include <vtkStructuredGridOutlineFilter.h>
#include <vtkContourFilter.h>
#include <vtkRuledSurfaceFilter.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>VTKStreamline::VTKStreamline(QWidget* parent): QMainWindow(parent)
{ui.setupUi(this);_pVTKWidget = new QVTKOpenGLNativeWidget();this->setCentralWidget(_pVTKWidget);// this->showMaximized();// 1. generate datavtkSmartPointer<vtkLineSource> seeds = vtkSmartPointer<vtkLineSource>::New();// 设置线段的端点seeds->SetPoint1(15, -5, 32);seeds->SetPoint2(15, 5, 32);seeds->SetResolution(21);// or, read data// vtkMultiBlockPLOT3DReader 是一个读取器对象,用于读取 PLOT3D 格式的文件并在输出时生成结构化网格vtkSmartPointer<vtkMultiBlockPLOT3DReader> plot3dReader = vtkSmartPointer<vtkMultiBlockPLOT3DReader>::New();plot3dReader->SetXYZFileName("combxyz.bin");plot3dReader->SetQFileName("combq.bin");plot3dReader->SetScalarFunctionNumber(100);plot3dReader->SetVectorFunctionNumber(202);qDebug() << plot3dReader->GetOutput()->GetNumberOfBlocks(); // 0// 反向更新管线plot3dReader->Update();qDebug() << plot3dReader->GetOutput()->GetNumberOfBlocks(); // 1vtkDataSet* plot3dOutput = (vtkDataSet*)(plot3dReader->GetOutput()->GetBlock(0));// 四阶龙格库塔 (Runge-Kutta) 求解微分vtkSmartPointer<vtkRungeKutta4> integ = vtkSmartPointer<vtkRungeKutta4>::New();// 通过整合矢量场生成流线vtkSmartPointer<vtkStreamTracer> streamer = vtkSmartPointer<vtkStreamTracer>::New();streamer->SetIntegrator(integ);streamer->SetInputData(plot3dOutput);streamer->SetStartPosition(15, 5, 32);streamer->SetMaximumPropagation(100);streamer->SetInitialIntegreationStep(0.1);streamer->SetIntegreationDirectionToBackward();vtkSmartPointer<vtkStreamTracer> streamer2 = vtkSmartPointer<vtkStreamTracer>::New();streamer2->SetIntegrator(integ);streamer2->SetInputData(plot3dOutput);// streamer2->SetStartPosition(15, 5, 32);streamer2->SetMaximumPropagation(100);streamer2->SetInitialIntegreationStep(0.1);streamer2->SetIntegreationDirectionToBackward();streamer2->SetSourceConnection(seeds->GetOutputPort());// 2. filter// 产生结构化栅格边界的一个线轮廓vtkSmartPointer<vtkStructuredGridOutlineFilter> outline = vtkSmartPointer<vtkStructuredGridOutlineFilter>::New();outline->SetInputData(plot3dOutput);vtkSmartPointer<vtkTubeFilter> streamTube = vtkSmartPointer<vtkTubeFilter>::New();streamTube->SetInputConnection(streamer->GetOutputPort());streamTube->SetRadius(0.06);streamTube->SetNumberOfSides(12);vtkSmartPointer<vtkRuledSurfaceFilter> scalarSurface = vtkSmartPointer<vtkRuledSurfaceFilter>::New();scalarSurface->SetInputConnection(streamer2->GetOutputPort());// 设置生成方法scalarSurface->SetRuledModeToPointWalk();scalarSurface->SetOnRatio(2);// 3. mappervtkSmartPointer<vtkPolyDataMapper> outlineMapper = vtkSmartPointer<vtkPolyDataMapper>::New();vtkSmartPointer<vtkPolyDataMapper> singleMapper = vtkSmartPointer<vtkPolyDataMapper>::New();singleMapper->SetScalarRange(plot3dOutput->GetPointData()->GetScalars()->GetRange());vtkSmartPointer<vtkPolyDataMapper> multipleMapper = vtkSmartPointer<vtkPolyDataMapper>::New();multipleMapper->SetScalarRange(plot3dOutput->GetPointData()->GetScalars()->GetRange());// 4. actorvtkSmartPointer<vtkActor> outlineActor = vtkSmartPointer<vtkActor>::New();vtkSmartPointer<vtkActor> singleActor = vtkSmartPointer<vtkActor>::New();vtkSmartPointer<vtkActor> multipleActor = vtkSmartPointer<vtkActor>::New();// 5. renderervtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();renderer->SetBackground(0.3, 0.6, 0.3); // Background Color: Green// 6. connectoutlineMapper->SetInputConnection(outline->GetOutputPort());singleMapper->SetInputConnection(streamTube->GetOutputPort());// multipleMapper->SetInputConnection(streamer2->GetOutputPort());multipleMapper->SetInputConnection(scalarSurface->GetOutputPort());outlineActor->SetMapper(outlineMapper);singleActor->SetMapper(singleMapper);multipleActor->SetMapper(multipleMapper);renderer->AddActor(outlineActor);renderer->AddActor(singleActor);renderer->AddActor(multipleActor);this->_pVTKWidget->renderWindow()->AddRenderer(renderer);this->_pVTKWidget->renderWindow()->Render();
}VTKStreamline::~VTKStreamline()
{}

这篇关于VTK 的可视化方法:流线、流管、流面、流带的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/956462

相关文章

MySQL查询JSON数组字段包含特定字符串的方法

《MySQL查询JSON数组字段包含特定字符串的方法》在MySQL数据库中,当某个字段存储的是JSON数组,需要查询数组中包含特定字符串的记录时传统的LIKE语句无法直接使用,下面小编就为大家介绍两种... 目录问题背景解决方案对比1. 精确匹配方案(推荐)2. 模糊匹配方案参数化查询示例使用场景建议性能优

关于集合与数组转换实现方法

《关于集合与数组转换实现方法》:本文主要介绍关于集合与数组转换实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、Arrays.asList()1.1、方法作用1.2、内部实现1.3、修改元素的影响1.4、注意事项2、list.toArray()2.1、方

Python中注释使用方法举例详解

《Python中注释使用方法举例详解》在Python编程语言中注释是必不可少的一部分,它有助于提高代码的可读性和维护性,:本文主要介绍Python中注释使用方法的相关资料,需要的朋友可以参考下... 目录一、前言二、什么是注释?示例:三、单行注释语法:以 China编程# 开头,后面的内容为注释内容示例:示例:四

一文详解Git中分支本地和远程删除的方法

《一文详解Git中分支本地和远程删除的方法》在使用Git进行版本控制的过程中,我们会创建多个分支来进行不同功能的开发,这就容易涉及到如何正确地删除本地分支和远程分支,下面我们就来看看相关的实现方法吧... 目录技术背景实现步骤删除本地分支删除远程www.chinasem.cn分支同步删除信息到其他机器示例步骤

在Golang中实现定时任务的几种高效方法

《在Golang中实现定时任务的几种高效方法》本文将详细介绍在Golang中实现定时任务的几种高效方法,包括time包中的Ticker和Timer、第三方库cron的使用,以及基于channel和go... 目录背景介绍目的和范围预期读者文档结构概述术语表核心概念与联系故事引入核心概念解释核心概念之间的关系

在Linux终端中统计非二进制文件行数的实现方法

《在Linux终端中统计非二进制文件行数的实现方法》在Linux系统中,有时需要统计非二进制文件(如CSV、TXT文件)的行数,而不希望手动打开文件进行查看,例如,在处理大型日志文件、数据文件时,了解... 目录在linux终端中统计非二进制文件的行数技术背景实现步骤1. 使用wc命令2. 使用grep命令

Python中Tensorflow无法调用GPU问题的解决方法

《Python中Tensorflow无法调用GPU问题的解决方法》文章详解如何解决TensorFlow在Windows无法识别GPU的问题,需降级至2.10版本,安装匹配CUDA11.2和cuDNN... 当用以下代码查看GPU数量时,gpuspython返回的是一个空列表,说明tensorflow没有找到

XML重复查询一条Sql语句的解决方法

《XML重复查询一条Sql语句的解决方法》文章分析了XML重复查询与日志失效问题,指出因DTO缺少@Data注解导致日志无法格式化、空指针风险及参数穿透,进而引发性能灾难,解决方案为在Controll... 目录一、核心问题:从SQL重复执行到日志失效二、根因剖析:DTO断裂引发的级联故障三、解决方案:修复

C++ 检测文件大小和文件传输的方法示例详解

《C++检测文件大小和文件传输的方法示例详解》文章介绍了在C/C++中获取文件大小的三种方法,推荐使用stat()函数,并详细说明了如何设计一次性发送压缩包的结构体及传输流程,包含CRC校验和自动解... 目录检测文件的大小✅ 方法一:使用 stat() 函数(推荐)✅ 用法示例:✅ 方法二:使用 fsee

Java继承映射的三种使用方法示例

《Java继承映射的三种使用方法示例》继承在Java中扮演着重要的角色,它允许我们创建一个类(子类),该类继承另一个类(父类)的所有属性和方法,:本文主要介绍Java继承映射的三种使用方法示例,需... 目录前言一、单表继承(Single Table Inheritance)1-1、原理1-2、使用方法1-