VTK 中的坐标变换 | 基础

VTK 中的坐标变换 | 基础

前情提要

之前提到过 VTK 的坐标系统:VTK 三维场景

在这里插入图片描述

VTK 坐标变换的三个原则

VTK 坐标变换的三个原则:

  • 对物体(们)进行变换和对摄像机进行变换能取得相同的效果。
  • 变换的本质是矩阵运算,所有的变换都能用一个矩阵表达。
  • 变换矩阵可以拆解成最基本的变换(移动、放缩、旋转)的有序组合。

预备知识

在计算机图形学中,我们用齐次坐标系表示坐标:

在这里插入图片描述

Translation 矩阵,用于移动物体的位置:

在这里插入图片描述

Translation 变换:

在这里插入图片描述

Scaling 矩阵,用于改变物体的大小:

在这里插入图片描述

Rotation 矩阵 —— X 轴旋转:

在这里插入图片描述

Rotation 矩阵 —— Y 轴旋转:

在这里插入图片描述

Rotation 矩阵 —— Z 轴旋转:

在这里插入图片描述

Rotation 矩阵 —— 自由旋转:

在这里插入图片描述

实例 1:旋转摄像机

在这里插入图片描述

编写一个 VTK 程序,读取一个模型并显示,同时显示坐标轴:

#include "VTKCoordinateTransform.h"

#include <vtkBYUReader.h>
#include <vtkNamedColors.h>
#include <vtkProperty.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkCamera.h>
#include <vtkRenderWindow.h>

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

    this->_pVTKWidget = new QVTKOpenGLNativeWidget();
    this->setCentralWidget(_pVTKWidget);
    // this->showMaximized();

    vtkNew<vtkRenderer> renderer;
    this->_pVTKWidget->renderWindow()->AddRenderer(renderer);
    this->_pVTKWidget->renderWindow()->Render();

    this->_widgetCamOrien = vtkCameraOrientationWidget::New();
    this->_widgetCamOrien->SetParentRenderer(renderer);
    this->_widgetCamOrien->On();

    vtkNew<vtkNamedColors> colors;

    vtkNew<vtkBYUReader> cow;
    cow->SetFileName("cow.g");

    vtkNew<vtkPolyDataMapper> mapper;
    mapper->SetInputConnection(cow->GetOutputPort());

    vtkNew<vtkActor> actor;
    actor->SetMapper(mapper);
    actor->GetProperty()->SetColor(colors->GetColor3d("Gold").GetData());

    renderer->AddActor(actor);
    renderer->SetBackground(colors->GetColor3d("DarkSlateGray").GetData());
}

VTKCoordinateTransform::~VTKCoordinateTransform()
{
    delete this->_pVTKWidget;
    this->_widgetCamOrien->Delete();
}

运行效果:

在这里插入图片描述

添加以下代码,将摄像机在水平方向上旋转 90 度:

renderer->GetActiveCamera()->Azimuth(90);
renderer->ResetCamera();

运行效果:

在这里插入图片描述

实例 2:使用 vtkTransform 对模型进行平移

#include "VTKCoordinateTransform.h"

#include <vtkBYUReader.h>
#include <vtkNamedColors.h>
#include <vtkTransform.h>
#include <vtkTransformFilter.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkCamera.h>
#include <vtkRenderWindow.h>

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

    this->_pVTKWidget = new QVTKOpenGLNativeWidget();
    this->setCentralWidget(_pVTKWidget);
    // this->showMaximized();

    vtkNew<vtkRenderer> renderer;
    this->_pVTKWidget->renderWindow()->AddRenderer(renderer);
    this->_pVTKWidget->renderWindow()->Render();

    this->_widgetCamOrien = vtkCameraOrientationWidget::New();
    this->_widgetCamOrien->SetParentRenderer(renderer);
    this->_widgetCamOrien->On();

    vtkNew<vtkNamedColors> colors;

    vtkNew<vtkBYUReader> cow;
    cow->SetFileName("cow.g");

    vtkNew<vtkPolyDataMapper> mapper;
    mapper->SetInputConnection(cow->GetOutputPort());

    vtkNew<vtkActor> actor;
    actor->SetMapper(mapper);
    actor->GetProperty()->SetColor(colors->GetColor3d("Gold").GetData());

    renderer->AddActor(actor);
    renderer->SetBackground(colors->GetColor3d("DarkSlateGray").GetData());

    vtkNew<vtkTransform> transform;
    transform->Translate(10, 0, 0);

    vtkNew<vtkTransformFilter> transFilter;
    transFilter->SetInputConnection(cow->GetOutputPort());
    transFilter->SetTransform(transform);

    vtkNew<vtkPolyDataMapper> transMapper;
    transMapper->SetInputConnection(transFilter->GetOutputPort());

    vtkNew<vtkActor> transActor;
    transActor->SetMapper(transMapper);
    transActor->GetProperty()->SetColor(colors->GetColor3d("Silver").GetData());

    renderer->AddActor(transActor);
}

VTKCoordinateTransform::~VTKCoordinateTransform()
{
    delete this->_pVTKWidget;
    this->_widgetCamOrien->Delete();
}

运行效果:

在这里插入图片描述

实例 3:使用 vtkTransform 对模型进行旋转

注释掉:

transform->Translate(10, 0, 0);

换成:

transform->RotateY(90);

运行效果:

在这里插入图片描述

或者换成:

transform->Translate(10, 0, 0);
transform->RotateY(90);
transform->Translate(-10, 0, 0);

运行效果:

在这里插入图片描述

其实,对 vtkActor 也可以直接旋转,仅推荐在做简单变换时使用:

actor->RotateY(45);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

UestcXiye

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值