VTK学习(入门级教程,包括安装和使用)~持续更新中

news2024/12/23 13:20:57

说明:研究QT+VTK有段时间了,准备把学到的东西分享给大家,这篇博客以VS+QT+VTK为主进行展开学习的。

VTK学习

  • VTK安装和使用教程
  • VTK入门级教程
    • 设计界面vtkStudy.ui的操作
    • vtkStudy.h
      • 头文件说明
      • 完整代码
    • vtkStudy.cpp
      • 绘制球体
      • 绘制长方体
      • 绘制圆柱
      • 绘制圆锥
      • 绘制圆台
      • 绘制圆弧台
      • 合并几何体
      • 完整代码
    • 运行结果

VTK安装和使用教程

详细VTK安装教程我写了一篇博客,博客链接: https://blog.csdn.net/HXX904/article/details/133639010?spm=1001.2014.3001.5502
VTK库导入VS教程,博客链接: https://blog.csdn.net/HXX904/article/details/133650565?spm=1001.2014.3001.5502
这些准备好之后,就可以开始QT+VTK代码编写之旅了。

VTK入门级教程

项目创建以及VTK库导入就不多说了,直接进入正题。

这是我创建的项目,项目名称大家随意起。

Alt

设计界面vtkStudy.ui的操作

创建一个Widge控件,选中Widget控件右击,点击提升为
Alt
在提升的类名称中编辑:QVTKOpenGLNativeWidget。然后点击添加。
Alt
进行勾选,并点击提升。
Alt

vtkStudy.h

头文件说明

//该头文件包含了用于生成球体几何数据的类。
#include <vtkSphereSource.h>

//该头文件包含了用于将vtkPolyData数据映射为可视化对象的类。
#include <vtkPolyDataMapper.h>

//该头文件包含了表示可视化对象的类,可以将vtkPolyDataMapper封装为一个可视化对象。
#include "vtkActor.h"

///该头文件包含了用于设置可视化对象属性(例如颜色、透明度等)的类。
#include <vtkProperty.h>

//该头文件包含了管理和渲染可视化对象的类,可以将多个vtkActor添加到vtkRenderer中进行渲染。
#include "vtkRenderer.h"

//该头文件包含了与特定平台无关的OpenGL渲染窗口类,用于在不同的图形界面(如Qt)中显示渲染结果。
#include <vtkGenericOpenGLRenderWindow.h>

//该头文件包含了用于生成立方体几何数据的类。
#include <vtkCubeSource.h>

//该头文件包含了用于生成线段几何数据的类。
#include <vtkLineSource.h>

//该头文件包含了用于从线段数据生成管道(圆柱体)几何数据的类。
#include <vtkTubeFilter.h>

//该头文件包含了用于生成圆锥几何数据的类。
#include <vtkConeSource.h>

//该头文件包含了用于旋转挤压操作,将2D几何数据沿轴线进行旋转和拉伸生成3D几何数据的类。
#include <vtkRotationalExtrusionFilter.h>

//该头文件包含了用于对vtkPolyData应用变换操作的类。
#include <vtkTransformPolyDataFilter.h>

//该头文件包含了表示几何变换的类,可以用于平移、旋转、缩放等操作。
#include <vtkTransform.h>

//该头文件包含了用于将多个vtkPolyData数据合并为一个vtkPolyData数据的类。
#include <vtkAppendPolyData.h>

//该头文件包含了用于生成参数样条曲线几何数据的类。
#include <vtkParametricSpline.h>

//该头文件包含了用于计算参数化函数的几何数据的类,可以根据给定的参数化函数生成几何数据。
#include <vtkParametricFunctionSource.h>

//该头文件包含了用于将任何vtkDataSet转换为vtkPolyData的类,可以将各种类型的几何数据转换为vtkPolyData进行后续处理和可视化。
#include <vtkGeometryFilter.h>

完整代码

#pragma once

#include <QtWidgets/QMainWindow>
#include "ui_vtkStudy.h"

#include <vtkSphereSource.h>
#include <vtkPolyDataMapper.h>
#include "vtkActor.h"
#include <vtkProperty.h>
#include "vtkRenderer.h"
#include <vtkGenericOpenGLRenderWindow.h>
#include <vtkCubeSource.h>
#include <vtkLineSource.h>
#include <vtkTubeFilter.h>
#include <vtkConeSource.h>
#include <vtkRotationalExtrusionFilter.h>
#include <vtkTransformPolyDataFilter.h>
#include <vtkTransform.h>
#include <vtkAppendPolyData.h>
#include <vtkParametricSpline.h>
#include <vtkParametricFunctionSource.h>
#include <vtkGeometryFilter.h>

class vtkStudy : public QMainWindow
{
    Q_OBJECT

    std::vector<vtkSmartPointer<vtkSphereSource>> sphereSources;    //用于保存多个球体源对象
    std::vector<vtkSmartPointer<vtkCubeSource>> cubeSources;        //用于保存多个长方体源对象
    std::vector<vtkSmartPointer<vtkTubeFilter>> tubeSources;        //用于保存多个柱体源对象
    std::vector<vtkSmartPointer<vtkTransformPolyDataFilter>> ctctransformFilter;//用于保存多个圆台源对象
    std::vector<vtkSmartPointer<vtkConeSource>> coneSources;        //用于保存多个圆锥体源对象
    std::vector<vtkSmartPointer<vtkTransformPolyDataFilter>> arctransformFilter;//用于保存多个圆弧台源对象

public:
    vtkStudy(QWidget *parent = nullptr);
    ~vtkStudy();

    //绘制常见的几何体
    void DrawSphere();//绘制球体

    void DrawCube();//绘制长方体

    void DrawCylinder();//绘制圆柱

    void DrawCone();//绘制圆锥

    void DrawCircularFrustum();//绘制圆台

    void DrawCircularArc();//绘制圆弧台

    void MergeGeometry();//合并创建的几何体

private:
    Ui::vtkStudyClass ui;
};

vtkStudy.cpp

绘制球体

    // 创建一个球体源
    vtkSmartPointer<vtkSphereSource> sphereSource =
        vtkSmartPointer<vtkSphereSource>::New();
    sphereSource->SetCenter(0.0, 0.0, 0.0);  // 设置球体中心坐标
    sphereSource->SetRadius(3);  // 设置球体半径
    sphereSource->SetPhiResolution(100);  // 设置球体的纬线分辨率
    sphereSource->SetThetaResolution(100);  // 设置球体的经线分辨率
    sphereSource->Update();  // 更新球体数据

绘制长方体

	// 创建立方体源对象
	vtkSmartPointer<vtkCubeSource> cubeSource =
		vtkSmartPointer<vtkCubeSource>::New();
		
	// 设置立方体的中心位置和长宽高
	cubeSource->SetCenter(4, 0, 0);  // 设置立方体中心坐标
	cubeSource->SetXLength(1);       // 设置立方体在 X 方向上的长度
	cubeSource->SetYLength(2);       // 设置立方体在 Y 方向上的长度
	cubeSource->SetZLength(3);       // 设置立方体在 Z 方向上的长度
	cubeSource->Update();    // 更新立方体源的信息

绘制圆柱

	// 创建线源对象
	vtkSmartPointer<vtkLineSource> line =
		vtkSmartPointer<vtkLineSource>::New();
		
	// 设置线的起点和终点坐标
	line->SetPoint1(6, 0, 0);
	line->SetPoint2(10, 0, 0);
	
	// 创建管道化处理对象
	vtkSmartPointer<vtkTubeFilter> tube
		= vtkSmartPointer<vtkTubeFilter>::New();
		
	// 将线源的输出连接到管道中
	tube->SetInputConnection(line->GetOutputPort());
	
	// 设置生成圆柱体的半径、边数以及是否封闭处理
	tube->SetRadius(2);           // 设置半径
	tube->SetNumberOfSides(100);  // 设置边数
	tube->SetCapping(1);          // 是否进行封闭处理,1 表示进行封闭处理
	tube->Update();	// 更新管道信息

绘制圆锥

	// 创建锥体源对象
	vtkSmartPointer<vtkConeSource> coneSource =
		vtkSmartPointer<vtkConeSource>::New();

	// 设置锥体的中心位置、底面半径、高度和分辨率
	coneSource->SetCenter(14, 0, 0);  // 设置锥体中心坐标
	coneSource->SetRadius(2);         // 设置底面半径
	coneSource->SetHeight(4);         // 设置高度
	coneSource->SetResolution(100);   // 设置分辨率

	// 更新锥体源的信息
	coneSource->Update();

绘制圆台

	// 创建存储点的对象
	vtkNew<vtkPoints> points;
	points->InsertPoint(0, 0, 0.0, 18);
	points->InsertPoint(1, 2, 0.0, 18);
	points->InsertPoint(2, 4, 0.0, 18 + 4);
	points->InsertPoint(3, 0.0, 0.0, 18 + 4);

	// 创建存储线段的对象
	vtkNew<vtkCellArray> lines;
	lines->InsertNextCell(4);  // 线段的点数
	lines->InsertCellPoint(0);
	lines->InsertCellPoint(1);
	lines->InsertCellPoint(2);
	lines->InsertCellPoint(3);

	// 创建 PolyData 对象,并设置点和线信息
	vtkNew<vtkPolyData> profile;
	profile->SetPoints(points);
	profile->SetLines(lines);

	// 创建旋转拉伸滤波器对象
	vtkSmartPointer<vtkRotationalExtrusionFilter> extrude =
		vtkSmartPointer<vtkRotationalExtrusionFilter>::New();
	extrude->SetInputData(profile);
	extrude->SetAngle(360.0);  // 完整的旋转一周
	extrude->SetResolution(100);

	// 创建旋转变换对象,并绕 Y 轴旋转 90 度
	vtkSmartPointer<vtkTransform> transform =
		vtkSmartPointer<vtkTransform>::New();
	transform->RotateY(90.0);

	// 创建 TransformPolyDataFilter 对象,并连接旋转拉伸滤波器的输出
	vtkSmartPointer<vtkTransformPolyDataFilter> transformFilter =
		vtkSmartPointer<vtkTransformPolyDataFilter>::New();
	transformFilter->SetInputConnection(extrude->GetOutputPort());
	transformFilter->SetTransform(transform);

绘制圆弧台

	// 创建线段1
	vtkSmartPointer<vtkLineSource> lineSource1 = vtkSmartPointer<vtkLineSource>::New();
	lineSource1->SetPoint1(3, 0, 24);
	lineSource1->SetPoint2(0, 0, 24);

	// 创建线段2
	vtkSmartPointer<vtkLineSource> lineSource2 = vtkSmartPointer<vtkLineSource>::New();
	lineSource2->SetPoint1(0, 0, 24);
	lineSource2->SetPoint2(0, 0, 30);

	// 创建线段3
	vtkSmartPointer<vtkLineSource> lineSource3 = vtkSmartPointer<vtkLineSource>::New();
	lineSource3->SetPoint1(0, 0, 30);
	lineSource3->SetPoint2(6, 0, 30);

	// 创建参数化样条曲线
	vtkSmartPointer<vtkParametricSpline> spline = vtkSmartPointer<vtkParametricSpline>::New();
	vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
	points->InsertNextPoint(6, 0, 30);

	double X1 = 6, Y1 = 30;
	double X2 = 3, Y2 = 24;
	double R = 10;

	// 计算两点连线的中点坐标
	double midX = (X1 + X2) / 2;
	double midY = (Y1 + Y2) / 2;

	// 计算两点连线的斜率
	double slope = (Y2 - Y1) / (X2 - X1);

	// 计算两点连线的垂直平分线斜率的倒数
	double perpendicularSlope = -1 / slope;

	// 计算两点连线的长度
	double distance = std::sqrt(std::pow((X2 - X1), 2) + std::pow((Y2 - Y1), 2));

	// 计算垂直平分线与两点连线中点的距离
	double perpendicularDistance = std::sqrt(std::pow(R, 2) - std::pow((distance / 2), 2));

	// 计算圆心坐标
	double x1 = midX + perpendicularDistance / std::sqrt(1 + std::pow(perpendicularSlope, 2));
	double y1 = midY + perpendicularSlope * (x1 - midX);
	double x2 = (X1 + X2) / 2, y2 = (Y1 + Y2) / 2;
	double CenterX = 2 * x2 - x1, CenterY = 2 * y2 - y1;

	double x3 = CenterX, y3 = CenterY;
	double x4 = (X1 + X2) / 2, y4 = (Y1 + Y2) / 2;
	double k = (y4 - y3) / (x4 - x3);
	double b = y3 - k * x3;
	double a = k * k + 1;
	double b2 = 2 * b * k - 2 * k * CenterY - 2 * CenterX;
	double c = CenterX * CenterX - R * R + (b - CenterY) * (b - CenterY);

	// 计算与圆相交的点坐标
	double X = (-1.0 * b2 + sqrt(b2 * b2 - 4 * a * c)) / (2 * a);
	double Y = k * X + b;

	// 添加样条曲线上的点
	points->InsertNextPoint(X, 0, Y);
	points->InsertNextPoint(3, 0, 24);
	spline->SetPoints(points);

	// 创建一个用于存储多个几何对象的容器
	vtkSmartPointer<vtkAppendPolyData> appendPolyData = vtkSmartPointer<vtkAppendPolyData>::New();

	// 将线段1添加到容器中
	appendPolyData->AddInputConnection(lineSource1->GetOutputPort());
	appendPolyData->Update();

	// 将线段2添加到容器中
	appendPolyData->AddInputConnection(lineSource2->GetOutputPort());
	appendPolyData->Update();

	// 将线段3添加到容器中
	appendPolyData->AddInputConnection(lineSource3->GetOutputPort());
	appendPolyData->Update();

	// 创建参数化函数的源对象
	vtkSmartPointer<vtkParametricFunctionSource> functionSource = vtkSmartPointer<vtkParametricFunctionSource>::New();
	functionSource->SetParametricFunction(spline);
	functionSource->Update();

	// 将参数化函数生成的曲线添加到容器中
	appendPolyData->AddInputConnection(functionSource->GetOutputPort());
	appendPolyData->Update();

	// 提取容器中的几何数据
	vtkSmartPointer<vtkGeometryFilter> geometryFilter = vtkSmartPointer<vtkGeometryFilter>::New();
	geometryFilter->SetInputData(appendPolyData->GetOutput());
	geometryFilter->Update();

	// 获取提取后的几何数据
	vtkSmartPointer<vtkPolyData> yprofiles = geometryFilter->GetOutput();

	// 创建旋转挤压滤波器
	vtkSmartPointer<vtkRotationalExtrusionFilter> extrude = vtkSmartPointer<vtkRotationalExtrusionFilter>::New();
	extrude->SetInputData(yprofiles);
	extrude->SetAngle(360);
	extrude->SetResolution(360);

	// 创建变换对象并绕Y轴旋转90度
	vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
	transform->RotateY(90.0);
	vtkSmartPointer<vtkTransformPolyDataFilter> transformFilter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
	transformFilter->SetInputConnection(extrude->GetOutputPort());
	transformFilter->SetTransform(transform);

合并几何体

	// 创建一个vtkAppendPolyData对象,用于将多个PolyData数据合并成一个
	vtkSmartPointer<vtkAppendPolyData> appendFilter = vtkSmartPointer<vtkAppendPolyData>::New();

	// 将各种类型的几何数据添加到vtkAppendPolyData对象中
	for (const auto& sphere : sphereSources) {
		sphere->Update();
		appendFilter->AddInputData(sphere->GetOutput());
	}

	for (const auto& cube : cubeSources) {
		cube->Update();
		appendFilter->AddInputData(cube->GetOutput());
	}

	for (const auto& tube : tubeSources) {
		tube->Update();
		appendFilter->AddInputData(tube->GetOutput());
	}

	for (const auto& ctc : ctctransformFilter) {
		ctc->Update();
		appendFilter->AddInputData(ctc->GetOutput());
	}

	for (const auto& cone : coneSources) {
		cone->Update();
		appendFilter->AddInputData(cone->GetOutput());
	}

	for (const auto& arc : arctransformFilter) {
		arc->Update();
		appendFilter->AddInputData(arc->GetOutput());
	}

	// 对合并后的vtkPolyData进行渲染,创建vtkPolyDataMapper对象
	vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
	mapper->SetInputConnection(appendFilter->GetOutputPort());

	// 创建vtkActor对象,并将vtkPolyDataMapper设置为其Mapper
	vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
	actor->SetMapper(mapper);

	// 设置Actor的颜色为红色
	actor->GetProperty()->SetColor(255.0 / 255.0, 0.0 / 255.0, 0.0 / 255.0);

	// 创建vtkRenderer对象,并设置背景颜色为黑色
	vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
	renderer->SetBackground(0, 0, 0);

	// 将Actor添加到Renderer中
	renderer->AddActor(actor);

	// 创建vtkGenericOpenGLRenderWindow对象,并将Renderer设置为其Renderer
	vtkSmartPointer<vtkGenericOpenGLRenderWindow> renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
	renderWindow->AddRenderer(renderer);

	// 将vtkGenericOpenGLRenderWindow对象设置为Qt界面上的RenderWindow
	ui.widget->setRenderWindow(renderWindow);

完整代码

#include "vtkStudy.h"

vtkStudy::vtkStudy(QWidget* parent)
	: QMainWindow(parent)
{
	ui.setupUi(this);

	//绘制常见的几何体
	DrawSphere();//绘制球体

	DrawCube();//绘制长方体

	DrawCylinder();//绘制圆柱

	DrawCone();//绘制圆锥

	DrawCircularFrustum();//绘制圆台

	DrawCircularArc();//绘制圆弧台

	MergeGeometry();//将绘制的几何体进行合并
}

vtkStudy::~vtkStudy()
{}

void vtkStudy::DrawSphere()
{
	// 创建一个球体源
	vtkSmartPointer<vtkSphereSource> sphereSource =
		vtkSmartPointer<vtkSphereSource>::New();
	sphereSource->SetCenter(0.0, 0.0, 0.0);  // 设置球体中心坐标
	sphereSource->SetRadius(2);  // 设置球体半径
	sphereSource->SetPhiResolution(100);  // 设置球体的纬线分辨率
	sphereSource->SetThetaResolution(100);  // 设置球体的经线分辨率
	sphereSource->Update();  // 更新球体数据
	sphereSources.push_back(sphereSource);
}

void vtkStudy::DrawCube()
{
	// 创建立方体源对象
	vtkSmartPointer<vtkCubeSource> cubeSource =
		vtkSmartPointer<vtkCubeSource>::New();

	// 设置立方体的中心位置和长宽高
	cubeSource->SetCenter(4, 0, 0);  // 设置立方体中心坐标
	cubeSource->SetXLength(1);       // 设置立方体在 X 方向上的长度
	cubeSource->SetYLength(2);       // 设置立方体在 Y 方向上的长度
	cubeSource->SetZLength(3);       // 设置立方体在 Z 方向上的长度

	cubeSource->Update();    // 更新立方体源的信息
	cubeSources.push_back(cubeSource);
}

void vtkStudy::DrawCylinder()
{
	// 创建线源对象
	vtkSmartPointer<vtkLineSource> line =
		vtkSmartPointer<vtkLineSource>::New();

	// 设置线的起点和终点坐标
	line->SetPoint1(6, 0, 0);
	line->SetPoint2(10, 0, 0);

	// 创建管道化处理对象
	vtkSmartPointer<vtkTubeFilter> tube
		= vtkSmartPointer<vtkTubeFilter>::New();

	// 将线源的输出连接到管道中
	tube->SetInputConnection(line->GetOutputPort());

	// 设置生成圆柱体的半径、边数以及是否封闭处理
	tube->SetRadius(2);           // 设置半径
	tube->SetNumberOfSides(100);  // 设置边数
	tube->SetCapping(1);          // 是否进行封闭处理,1 表示进行封闭处理

	// 更新管道信息
	tube->Update();
	tubeSources.push_back(tube);

}

void vtkStudy::DrawCone()
{
	// 创建锥体源对象
	vtkSmartPointer<vtkConeSource> coneSource =
		vtkSmartPointer<vtkConeSource>::New();

	// 设置锥体的中心位置、底面半径、高度和分辨率
	coneSource->SetCenter(14, 0, 0);  // 设置锥体中心坐标
	coneSource->SetRadius(2);         // 设置底面半径
	coneSource->SetHeight(4);         // 设置高度
	coneSource->SetResolution(100);   // 设置分辨率

	// 更新锥体源的信息
	coneSource->Update();
	coneSources.push_back(coneSource);
}

void vtkStudy::DrawCircularFrustum()
{
	// 创建存储点的对象
	vtkNew<vtkPoints> points;
	points->InsertPoint(0, 0, 0.0, 18);
	points->InsertPoint(1, 2, 0.0, 18);
	points->InsertPoint(2, 4, 0.0, 18 + 4);
	points->InsertPoint(3, 0.0, 0.0, 18 + 4);

	// 创建存储线段的对象
	vtkNew<vtkCellArray> lines;
	lines->InsertNextCell(4);  // 线段的点数
	lines->InsertCellPoint(0);
	lines->InsertCellPoint(1);
	lines->InsertCellPoint(2);
	lines->InsertCellPoint(3);

	// 创建 PolyData 对象,并设置点和线信息
	vtkNew<vtkPolyData> profile;
	profile->SetPoints(points);
	profile->SetLines(lines);

	// 创建旋转拉伸滤波器对象
	vtkSmartPointer<vtkRotationalExtrusionFilter> extrude =
		vtkSmartPointer<vtkRotationalExtrusionFilter>::New();
	extrude->SetInputData(profile);
	extrude->SetAngle(360.0);  // 完整的旋转一周
	extrude->SetResolution(100);

	// 创建旋转变换对象,并绕 Y 轴旋转 90 度
	vtkSmartPointer<vtkTransform> transform =
		vtkSmartPointer<vtkTransform>::New();
	transform->RotateY(90.0);

	// 创建 TransformPolyDataFilter 对象,并连接旋转拉伸滤波器的输出
	vtkSmartPointer<vtkTransformPolyDataFilter> transformFilter =
		vtkSmartPointer<vtkTransformPolyDataFilter>::New();
	transformFilter->SetInputConnection(extrude->GetOutputPort());
	transformFilter->SetTransform(transform);

	ctctransformFilter.push_back(transformFilter);
}

void vtkStudy::DrawCircularArc()
{
	// 创建线段1
	vtkSmartPointer<vtkLineSource> lineSource1 = vtkSmartPointer<vtkLineSource>::New();
	lineSource1->SetPoint1(3, 0, 24);
	lineSource1->SetPoint2(0, 0, 24);

	// 创建线段2
	vtkSmartPointer<vtkLineSource> lineSource2 = vtkSmartPointer<vtkLineSource>::New();
	lineSource2->SetPoint1(0, 0, 24);
	lineSource2->SetPoint2(0, 0, 30);

	// 创建线段3
	vtkSmartPointer<vtkLineSource> lineSource3 = vtkSmartPointer<vtkLineSource>::New();
	lineSource3->SetPoint1(0, 0, 30);
	lineSource3->SetPoint2(6, 0, 30);

	// 创建参数化样条曲线
	vtkSmartPointer<vtkParametricSpline> spline = vtkSmartPointer<vtkParametricSpline>::New();
	vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
	points->InsertNextPoint(6, 0, 30);

	double X1 = 6, Y1 = 30;
	double X2 = 3, Y2 = 24;
	double R = 10;

	// 计算两点连线的中点坐标
	double midX = (X1 + X2) / 2;
	double midY = (Y1 + Y2) / 2;

	// 计算两点连线的斜率
	double slope = (Y2 - Y1) / (X2 - X1);

	// 计算两点连线的垂直平分线斜率的倒数
	double perpendicularSlope = -1 / slope;

	// 计算两点连线的长度
	double distance = std::sqrt(std::pow((X2 - X1), 2) + std::pow((Y2 - Y1), 2));

	// 计算垂直平分线与两点连线中点的距离
	double perpendicularDistance = std::sqrt(std::pow(R, 2) - std::pow((distance / 2), 2));

	// 计算圆心坐标
	double x1 = midX + perpendicularDistance / std::sqrt(1 + std::pow(perpendicularSlope, 2));
	double y1 = midY + perpendicularSlope * (x1 - midX);
	double x2 = (X1 + X2) / 2, y2 = (Y1 + Y2) / 2;
	double CenterX = 2 * x2 - x1, CenterY = 2 * y2 - y1;

	double x3 = CenterX, y3 = CenterY;
	double x4 = (X1 + X2) / 2, y4 = (Y1 + Y2) / 2;
	double k = (y4 - y3) / (x4 - x3);
	double b = y3 - k * x3;
	double a = k * k + 1;
	double b2 = 2 * b * k - 2 * k * CenterY - 2 * CenterX;
	double c = CenterX * CenterX - R * R + (b - CenterY) * (b - CenterY);

	// 计算与圆相交的点坐标
	double X = (-1.0 * b2 + sqrt(b2 * b2 - 4 * a * c)) / (2 * a);
	double Y = k * X + b;

	// 添加样条曲线上的点
	points->InsertNextPoint(X, 0, Y);
	points->InsertNextPoint(3, 0, 24);
	spline->SetPoints(points);

	// 创建一个用于存储多个几何对象的容器
	vtkSmartPointer<vtkAppendPolyData> appendPolyData = vtkSmartPointer<vtkAppendPolyData>::New();

	// 将线段1添加到容器中
	appendPolyData->AddInputConnection(lineSource1->GetOutputPort());
	appendPolyData->Update();

	// 将线段2添加到容器中
	appendPolyData->AddInputConnection(lineSource2->GetOutputPort());
	appendPolyData->Update();

	// 将线段3添加到容器中
	appendPolyData->AddInputConnection(lineSource3->GetOutputPort());
	appendPolyData->Update();

	// 创建参数化函数的源对象
	vtkSmartPointer<vtkParametricFunctionSource> functionSource = vtkSmartPointer<vtkParametricFunctionSource>::New();
	functionSource->SetParametricFunction(spline);
	functionSource->Update();

	// 将参数化函数生成的曲线添加到容器中
	appendPolyData->AddInputConnection(functionSource->GetOutputPort());
	appendPolyData->Update();

	// 提取容器中的几何数据
	vtkSmartPointer<vtkGeometryFilter> geometryFilter = vtkSmartPointer<vtkGeometryFilter>::New();
	geometryFilter->SetInputData(appendPolyData->GetOutput());
	geometryFilter->Update();

	// 获取提取后的几何数据
	vtkSmartPointer<vtkPolyData> yprofiles = geometryFilter->GetOutput();

	// 创建旋转挤压滤波器
	vtkSmartPointer<vtkRotationalExtrusionFilter> extrude = vtkSmartPointer<vtkRotationalExtrusionFilter>::New();
	extrude->SetInputData(yprofiles);
	extrude->SetAngle(360);
	extrude->SetResolution(360);

	// 创建变换对象并绕Y轴旋转90度
	vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
	transform->RotateY(90.0);
	vtkSmartPointer<vtkTransformPolyDataFilter> transformFilter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
	transformFilter->SetInputConnection(extrude->GetOutputPort());
	transformFilter->SetTransform(transform);

	// 将变换后的数据添加到一个容器中(这里没有给出arctransformFilter的定义,需要自行定义)
	arctransformFilter.push_back(transformFilter);

}

void vtkStudy::MergeGeometry()
{
	// 创建一个vtkAppendPolyData对象,用于将多个PolyData数据合并成一个
	vtkSmartPointer<vtkAppendPolyData> appendFilter = vtkSmartPointer<vtkAppendPolyData>::New();

	// 将各种类型的几何数据添加到vtkAppendPolyData对象中
	for (const auto& sphere : sphereSources) {
		sphere->Update();
		appendFilter->AddInputData(sphere->GetOutput());
	}

	for (const auto& cube : cubeSources) {
		cube->Update();
		appendFilter->AddInputData(cube->GetOutput());
	}

	for (const auto& tube : tubeSources) {
		tube->Update();
		appendFilter->AddInputData(tube->GetOutput());
	}

	for (const auto& ctc : ctctransformFilter) {
		ctc->Update();
		appendFilter->AddInputData(ctc->GetOutput());
	}

	for (const auto& cone : coneSources) {
		cone->Update();
		appendFilter->AddInputData(cone->GetOutput());
	}

	for (const auto& arc : arctransformFilter) {
		arc->Update();
		appendFilter->AddInputData(arc->GetOutput());
	}

	// 对合并后的vtkPolyData进行渲染,创建vtkPolyDataMapper对象
	vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
	mapper->SetInputConnection(appendFilter->GetOutputPort());

	// 创建vtkActor对象,并将vtkPolyDataMapper设置为其Mapper
	vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
	actor->SetMapper(mapper);

	// 设置Actor的颜色为红色
	actor->GetProperty()->SetColor(255.0 / 255.0, 0.0 / 255.0, 0.0 / 255.0);

	// 创建vtkRenderer对象,并设置背景颜色为黑色
	vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
	renderer->SetBackground(0, 0, 0);

	// 将Actor添加到Renderer中
	renderer->AddActor(actor);

	// 创建vtkGenericOpenGLRenderWindow对象,并将Renderer设置为其Renderer
	vtkSmartPointer<vtkGenericOpenGLRenderWindow> renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
	renderWindow->AddRenderer(renderer);

	// 将vtkGenericOpenGLRenderWindow对象设置为Qt界面上的RenderWindow
	ui.widget->setRenderWindow(renderWindow);
}

运行结果

可进行缩放、旋转、平移。
ALT

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1304693.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

wordpress多語言插件Polylang與GTranslate會有衝突

wordpress多語言插件Polylang與GTranslate會有衝突,會導致分頁顯示不完整&#xff0c;需要禁用或卸載其中一個 分頁顯示才會沒問題 GTranslate必須要先按一種語言編輯好你要發佈網站&#xff0c;GTranslate這種語言為基礎去翻譯出來&#xff0c;其實內裡是套用了google 翻譯的…

第二证券:结构性行情或将延续 泛科技有望继续走强

展望未来&#xff0c;当时已进入重要的方针窗口期&#xff0c;能否有超预期的新方针推出是改变商场的要害。但复盘2023年的行情来看&#xff0c;过早买卖方针预期的成功率并不高&#xff0c;因而主张该方位以防御性资产为主&#xff0c;高股息资产从本年9月份至今现已调整了2个…

ubuntu dns 相关

查看dns配置 systemd-resolve --status 修改dns vim /etc/resolv.conf sudo apt install traceroute 追踪 traceroute www.baidu.com

windows下docker环境安装

开启硬件虚拟化技术 win10中开启 Hyper-V Win10 下是否开启硬件虚拟化技术&#xff0c;在控制面板&#xff0c;启用 window 功能&#xff0c;找到 Hyper-V 选项&#xff0c;点勾选确认。如图&#xff1a; Windows 11 家庭中文版新增 Hyper-V选项 注意以下的解决方案来自win1…

Vision Transformer模型架构详解

&#x1f380;个人主页&#xff1a; https://zhangxiaoshu.blog.csdn.net &#x1f4e2;欢迎大家&#xff1a;关注&#x1f50d;点赞&#x1f44d;评论&#x1f4dd;收藏⭐️&#xff0c;如有错误敬请指正! &#x1f495;未来很长&#xff0c;值得我们全力奔赴更美好的生活&…

自动化测试 (一) 12306火车票网站自动登录工具

还记得2011年春运&#xff0c;12306火车票预订网站经常崩溃无法登录吗。 今天我们就开发一个12306网站自动登录软件。 帮助您轻松订票 Web的原理就是&#xff0c;浏览器发送一个Request给Web服务器&#xff0c;Web服务器处理完这个请求之后发送一个HTTP Response给浏览器。 …

【JAVA】黑马MybatisPlus 学习笔记【一】

1.快速入门 为了方便测试&#xff0c;我们先创建一个新的项目&#xff0c;并准备一些基础数据。 1.1 环境配置 导入项目 注意配置一下项目的JDK版本为JDK11。首先点击项目结构设置&#xff1a; 导入两张表&#xff0c;在课前资料中已经提供了SQL文件&#xff1a; 最后&am…

python用来干什么的,python用来做什么的

大家好&#xff0c;小编来为大家解答以下问题&#xff0c;python用来干什么的&#xff0c;python用来做什么的&#xff0c;今天让我们一起来看看吧&#xff01; 随着互联网行业的发展&#xff0c;编程越来越受到人们的重视&#xff0c;但是始终很多人并不了解编程是什么&#x…

Linux——MySQL数据库系统

一、 MySQL的编译安装 1、准备工作 &#xff08;1&#xff09;为了避免发生端口冲突&#xff0c;程序冲突等现象&#xff0c;建议先查询MySQL软件的安装情况&#xff0c;确认没有使用以Rpm方式安装的mysql-server、mysql软件包&#xff0c;否则建议将其卸载 [rootlocalhost ~]…

13、RockerMQ消息类型之广播与集群消息

RocketMq中提供两种消费模式&#xff1a;集群模式和广播模式。 集群模式 集群模式表示同一个消息会被同一个消费组中的消费者消费一次&#xff0c;消息被负载均衡分配到同一个消费者上的多个实例上。 还有另外一种平均的算法是AllocateMessageQueueAveragelyByCircle&#xff…

element table表格内进行表单验证(简单例子,一看就会,亲测有用~)开箱即用!!

效果图&#xff1a; 代码&#xff1a; <div> <el-form ref"form" :model"form" ><el-table :data"form.tableData" align"center" border><el-table-column label"名称"><template slot-scope&…

国标GB28181安防视频云平台EasyCVR出现持续重启现象,是什么问题?该如何解决?

视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安防视频监控的能…

边缘计算系统设计与实践

随着科技的飞速发展&#xff0c;物联网和人工智能两大领域的不断突破&#xff0c;我们看到了一种新型的计算模型——边缘计算的崛起。这种计算模型在处理大规模数据、实现实时响应和降低延迟需求方面&#xff0c;展现出了巨大的潜力。本文将深入探讨边缘计算系统的设计原理和实…

MySQL5 和 MySQL8 的配置区别 一些注意事项

1、使用命令行查看MySQL的版本 先保证你的mysql正在运行&#xff0c;假如用户名是root&#xff0c;密码是123456&#xff0c;运行下边的代码可以查看mysql的版本号。 mysql -uroot -p123456这里我的版本是5.7.19。也就是5版本的。 2、不同版本对应的数据库驱动jar包&#x…

【docker 】 安装docker(centOS7)

官网 docker官网 github源码 官网 在CentOS上安装Docker引擎 官网 在Debian上安装Docker引擎 官网 在 Fedora上安装Docker引擎 官网 在ubuntu上安装Docker引擎 官网 在RHEL (s390x)上安装Docker引擎 官网 在SLES上安装Docker引擎 最完善的资料都在官网。 卸载旧版本 …

AOP跨模块捕获异常遭CGLIB拦截而继续向上抛出异常

其他系列文章导航 Java基础合集数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 文章目录 其他系列文章导航 文章目录 前言 一、BUG详情 1.1 报错信息 1.2 接口响应信息 1.3 全局异常处理器的定义 二、排查过程 三、解决方案 四、总结 前言 最近&…

【SpringBoot】入门精简

目录 一、初识 SpringBoot 1.1 介绍 1.2 项目创建 1.3 目录结构 1.4 修改配置 二、SpringBoot 集成 2.1 集成 Mybatis框架 2.2 集成 Pagehepler分页插件 2.3 集成 Druid数据库连接池 2.4 集成 Log日志管理 一、初识 SpringBoot 1.1 介绍 Spring Boot是一个用于简化Sp…

无人零售柜:快捷舒适购物体验

无人零售柜&#xff1a;快捷舒适购物体验 通过无人零售柜和人工智能技术&#xff0c;消费者在购物过程中可以自由选择商品&#xff0c;根据个人需求和喜好查询商品清单。这种自主选择的购物环境能够为消费者提供更加舒适和满意的体验。此外&#xff0c;无人零售柜还具有节约时间…

Python手撕kmeans源码

参考了两篇文章 K-Means及K-Means算法Python源码实现-CSDN博客 使用K-means算法进行聚类分析_kmeans聚类分析结果怎么看-CSDN博客 # 定义kmeans类 from copy import deepcopy from sklearn.datasets import make_blobs import numpy as np import matplotlib.pyplot as pltc…

如何充分准备面试,迅速融入团队并在工作中取得卓越成就

首先&#xff0c;关于如何筹备面试&#xff0c;首先需要对所申请公司与职位进行深入的调查了解&#xff0c;并依据可能提出的面试问题预先准备相应的答案&#xff0c;并提前调试面试所需的仪器设备。同时&#xff0c;也要注重自身形象的塑造。更为关键的是 1. 在计算机领域的面…