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

相关文章

Java 中的 @SneakyThrows 注解使用方法(简化异常处理的利与弊)

《Java中的@SneakyThrows注解使用方法(简化异常处理的利与弊)》为了简化异常处理,Lombok提供了一个强大的注解@SneakyThrows,本文将详细介绍@SneakyThro... 目录1. @SneakyThrows 简介 1.1 什么是 Lombok?2. @SneakyThrows

判断PyTorch是GPU版还是CPU版的方法小结

《判断PyTorch是GPU版还是CPU版的方法小结》PyTorch作为当前最流行的深度学习框架之一,支持在CPU和GPU(NVIDIACUDA)上运行,所以对于深度学习开发者来说,正确识别PyTor... 目录前言为什么需要区分GPU和CPU版本?性能差异硬件要求如何检查PyTorch版本?方法1:使用命

Qt实现网络数据解析的方法总结

《Qt实现网络数据解析的方法总结》在Qt中解析网络数据通常涉及接收原始字节流,并将其转换为有意义的应用层数据,这篇文章为大家介绍了详细步骤和示例,感兴趣的小伙伴可以了解下... 目录1. 网络数据接收2. 缓冲区管理(处理粘包/拆包)3. 常见数据格式解析3.1 jsON解析3.2 XML解析3.3 自定义

SpringMVC 通过ajax 前后端数据交互的实现方法

《SpringMVC通过ajax前后端数据交互的实现方法》:本文主要介绍SpringMVC通过ajax前后端数据交互的实现方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价... 在前端的开发过程中,经常在html页面通过AJAX进行前后端数据的交互,SpringMVC的controll

Java中的工具类命名方法

《Java中的工具类命名方法》:本文主要介绍Java中的工具类究竟如何命名,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录Java中的工具类究竟如何命名?先来几个例子几种命名方式的比较到底如何命名 ?总结Java中的工具类究竟如何命名?先来几个例子JD

Spring Security自定义身份认证的实现方法

《SpringSecurity自定义身份认证的实现方法》:本文主要介绍SpringSecurity自定义身份认证的实现方法,下面对SpringSecurity的这三种自定义身份认证进行详细讲解,... 目录1.内存身份认证(1)创建配置类(2)验证内存身份认证2.JDBC身份认证(1)数据准备 (2)配置依

使用Python实现矢量路径的压缩、解压与可视化

《使用Python实现矢量路径的压缩、解压与可视化》在图形设计和Web开发中,矢量路径数据的高效存储与传输至关重要,本文将通过一个Python示例,展示如何将复杂的矢量路径命令序列压缩为JSON格式,... 目录引言核心功能概述1. 路径命令解析2. 路径数据压缩3. 路径数据解压4. 可视化代码实现详解1

python获取网页表格的多种方法汇总

《python获取网页表格的多种方法汇总》我们在网页上看到很多的表格,如果要获取里面的数据或者转化成其他格式,就需要将表格获取下来并进行整理,在Python中,获取网页表格的方法有多种,下面就跟随小编... 目录1. 使用Pandas的read_html2. 使用BeautifulSoup和pandas3.

Python 交互式可视化的利器Bokeh的使用

《Python交互式可视化的利器Bokeh的使用》Bokeh是一个专注于Web端交互式数据可视化的Python库,本文主要介绍了Python交互式可视化的利器Bokeh的使用,具有一定的参考价值,感... 目录1. Bokeh 简介1.1 为什么选择 Bokeh1.2 安装与环境配置2. Bokeh 基础2

Spring 中的循环引用问题解决方法

《Spring中的循环引用问题解决方法》:本文主要介绍Spring中的循环引用问题解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录什么是循环引用?循环依赖三级缓存解决循环依赖二级缓存三级缓存本章来聊聊Spring 中的循环引用问题该如何解决。这里聊