手动仿射变换


开发环境:

  1. Windows 11 家庭中文版
  2. Microsoft Visual Studio Community 2019
  3. VTK-9.3.0.rc0
  4. vtk-example
  5. 参考代码
  6. 目的:学习与总结

demo解决问题:通过仿射控件vtkAffineWidget对目标actor进行手动的拖拽的仿射变换

关键类:vtkAffineWidget

仿射变换概念参考链接
在这里插入图片描述

关键代码说明及效果展示:

  1. 获取仿射控件的transtorm,并设置到需要同等仿射变换的actor中
  this->AffineRep->GetTransform(this->Transform);this->Actor->SetUserTransform(this->Transform);
  1. SetUserTransform详细说明:(需要重点理解user的含义)
  /*** In addition to the instance variables such as position and orientation, you can add an additional transformation for your own use.  * This transformation is concatenated with the actor's internal transformation, which you implicitly create through the use of SetPosition(), SetOrigin() and SetOrientation().* If the internal transformation is identity (i.e. if you don't set the Position, Origin, or Orientation) then the actors final transformation will be the UserTransform, concatenated with the UserMatrix if the UserMatrix is present.*//*** 除了位置和方向等实例变量外,您还可以添加额外的变换供自己使用。 * 此转换与 actor 的内部转换连接,通过使用 SetPosition()、SetOrigin() 和 SetOrientation() 隐式创建。* 如果内部转换是 identity(即,如果您没有设置 Position、Origin 或 Orientation),则 actor 的最终转换将是 UserTransform,如果存在 UserMatrix,则与 UserMatrix 串联。*/

在这里插入图片描述
3. affineWidget添加观察者对象

  affineWidget->AddObserver(vtkCommand::InteractionEvent, affineCallback);affineWidget->AddObserver(vtkCommand::EndInteractionEvent, affineCallback);//这里可以考虑使用renderWindowInteractor进行回调,但是回调中需要判断操作对象是否为放射控件,比较繁琐//renderWindowInteractor->AddObserver(vtkCommand::InteractionEvent,affineCallback);//renderWindowInteractor->AddObserver(vtkCommand::EndInteractionEvent,affineCallback);
  1. 成员函数:SetRepresentationToWireframe()
    在这里插入图片描述

  2. GrandientBackgroundOn(开启渐变色)、SetBackground(底部颜色设置)、SetBackground2(顶部颜色设置)
    在这里插入图片描述
    在这里插入图片描述


#include <vtkActor.h>
#include <vtkAffineRepresentation2D.h>
#include <vtkAffineWidget.h>
#include <vtkAppendPolyData.h>
#include <vtkCallbackCommand.h>
#include <vtkCommand.h>
#include <vtkInteractorStyleSwitch.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPlaneSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkSphereSource.h>
#include <vtkTransform.h>namespace {
class vtkAffineCallback : public vtkCallbackCommand
{
public:static vtkAffineCallback* New(){return new vtkAffineCallback;}virtual void Execute(vtkObject* caller, unsigned long, void*);vtkAffineCallback() : Actor(0), AffineRep(0){this->Transform = vtkTransform::New();}~vtkAffineCallback(){this->Transform->Delete();}vtkActor* Actor;vtkAffineRepresentation2D* AffineRep;vtkTransform* Transform;
};
} // namespaceint main(int, char*[])
{vtkNew<vtkNamedColors> colors;// Create two spheres: a larger one and a smaller one on top of the larger one// to show a reference point while rotatingvtkNew<vtkSphereSource> sphereSource;//大球sphereSource->Update();std::cout << "sphereSource radius: " <<  sphereSource->GetRadius() << std::endl;//0.5std::cout << "sphereSource center: " << sphereSource->GetCenter()[0] << " "<< sphereSource->GetCenter()[1] << " "<< sphereSource->GetCenter()[2] << " "<< std::endl; // 0 0 0vtkNew<vtkSphereSource> sphereSource2;//小球(中心刚好位于大球正上方边缘处)sphereSource2->SetRadius(0.075);sphereSource2->SetCenter(0, 0.5, 0);sphereSource2->Update();// Append the two spheres into one vtkPolyDatavtkNew<vtkAppendPolyData> append;append->AddInputConnection(sphereSource->GetOutputPort());append->AddInputConnection(sphereSource2->GetOutputPort());// Create a plane centered over the larger sphere with 4x4 sub sectionsvtkNew<vtkPlaneSource> planeSource;planeSource->SetXResolution(4);planeSource->SetYResolution(4);planeSource->SetOrigin(-1, -1, 0);    //左下角planeSource->SetPoint1(1, -1, 0);     //右下角planeSource->SetPoint2(-1, 1, 0);     //左上角// Create a mapper and actor for the plane: show it as a wireframevtkNew<vtkPolyDataMapper> planeMapper;planeMapper->SetInputConnection(planeSource->GetOutputPort());vtkNew<vtkActor> planeActor;planeActor->SetMapper(planeMapper);planeActor->GetProperty()->SetRepresentationToWireframe();//设置表现形式为线形边框;否则为面板planeActor->GetProperty()->SetColor(colors->GetColor3d("Red").GetData());//设置线形边框为欸红色// Create a mapper and actor for the spheresvtkNew<vtkPolyDataMapper> mapper;mapper->SetInputConnection(append->GetOutputPort());vtkNew<vtkActor> actor;actor->SetMapper(mapper);actor->GetProperty()->SetRepresentationToWireframe(); //只有线构成的球体// Create a renderer and render windowvtkNew<vtkRenderer> renderer;vtkNew<vtkRenderWindow> renderWindow;renderWindow->AddRenderer(renderer);renderWindow->SetWindowName("AffineWidget");renderer->AddActor(actor);renderer->AddActor(planeActor);renderer->GradientBackgroundOn();                                         // 开启渐变色背景设置renderer->SetBackground(colors->GetColor3d("LightSkyBlue").GetData());    // 设置页面底部颜色值renderer->SetBackground2(colors->GetColor3d("MidnightBlue").GetData());   // 设置页面顶部颜色值// Create an interactorvtkNew<vtkRenderWindowInteractor> renderWindowInteractor;renderWindowInteractor->SetRenderWindow(renderWindow);dynamic_cast<vtkInteractorStyleSwitch*>(renderWindowInteractor->GetInteractorStyle())->SetCurrentStyleToTrackballCamera();//设置交互对象是相机,形式是trackball// Create an affine widget to manipulate the actor// the widget currently only has a 2D representation and therefore applies// transforms in the X-Y plane onlyvtkNew<vtkAffineWidget> affineWidget;affineWidget->SetInteractor(renderWindowInteractor);affineWidget->CreateDefaultRepresentation();dynamic_cast<vtkAffineRepresentation2D*>(affineWidget->GetRepresentation())->PlaceWidget(actor->GetBounds());//设置放射操作控件的位置在actor的外接矩形正中间//定义仿射控件交互事件对应的回调对象,并添加到观察者列表中,交互时进行通知vtkNew<vtkAffineCallback> affineCallback;affineCallback->Actor = actor;affineCallback->AffineRep = dynamic_cast<vtkAffineRepresentation2D*>(affineWidget->GetRepresentation());affineWidget->AddObserver(vtkCommand::InteractionEvent, affineCallback);affineWidget->AddObserver(vtkCommand::EndInteractionEvent, affineCallback);//这里可以考虑使用renderWindowInteractor进行回调,但是回调中需要判断操作对象是否为放射控件,比较繁琐//renderWindowInteractor->AddObserver(vtkCommand::InteractionEvent,affineCallback);//renderWindowInteractor->AddObserver(vtkCommand::EndInteractionEvent,affineCallback);renderWindow->Render();renderWindowInteractor->Initialize();renderWindow->Render();affineWidget->On();// begin mouse interactionrenderWindowInteractor->Start();return EXIT_SUCCESS;
}namespace {
void vtkAffineCallback::Execute(vtkObject*, unsigned long vtkNotUsed(event),void*)
{this->AffineRep->GetTransform(this->Transform);this->Actor->SetUserTransform(this->Transform);
}
} // namespace

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

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

相关文章

LSF 守护程序和进程、集群通信路径和安全模型

LSF 细观 了解在 LSF 主机上运行的各种守护进程&#xff0c;LSF 集群通信路径&#xff0c;以及 LSF 如何容许集群中的主机故障。 1、LSF 守护程序和进程 集群中的每个主机上都运行多个 LSF 进程。 正在运行的进程的类型和数量&#xff0c;取决于主机是主节点还是计算节点。 主…

WINCC7.5-根据时间跨度选择趋势

yyyy-MM-dd hh:mm:ss “yyyy”&#xff1a;表示四位数的年份&#xff0c;例如&#xff1a;2022。 “MM”&#xff1a;表示两位数的月份&#xff0c;从01到12。 “dd”&#xff1a;表示两位数的日期&#xff0c;从01到31。 “hh”&#xff1a;表示12小时制的小时数&#xff0c;从…

HackTheBox-Starting Point--Tier 1---Tactics

文章目录 一 题目二 实验过程三 Psexec工具使用 一 题目 Tags Network、Protocols、SMB、Reconnaissance、Misconfiguration译文&#xff1a;网络、协议、中小企业、侦察、配置错误Connect To attack the target machine, you must be on the same network.Connect to the S…

重要—01:Redis

目录 一、什么是Redis&#xff1f; 二、Redis如何实现高可用 三、缓存与数据库不一致问题 四、Redis持久化方式 五、6种淘汰策略 六、缓存穿透和缓存雪崩 七、Redis实现分布式锁 八、Redis.conf 配置文件详解 九、常用命令 一、什么是Redis&#xff1f; Redis&#xf…

TypeScript面试知识点?

以下是一些常见的TypeScript面试知识点,可能会在TypeScript相关的面试中被问到: 1:TypeScript的优势和用途: 解释TypeScript相对于JavaScript的优势,如静态类型检查、提供更好的开发工具支持、增加代码可读性和可维护性等。描述在什么情况下选择使用TypeScript,并举例说…

rcore 笔记 批处理系统 邓氏鱼

批处理系统 批处理系统 (Batch System) &#xff0c;它可用来管理无需或仅需少量用户交互即可运行的程序&#xff0c;在资源允许的情况下它可以自动安排程序的执行&#xff0c;这被称为“批处理作业”。 特权机制 实现特权级机制的根本原因是应用程序运行的安全性不可充分信…

docker安装Kafka,SpringBoot整合Kafka

#拉取镜像 docker pull wurstmeister/zookeeper #运行容器 docker run --restartalways --name zookeeper -p 2181:2181 \ -v /etc/localtime:/etc/localtime -d wurstmeister/zookeeper#拉取镜像 docker pull wurstmeister/kafka#运行容器 docker run --restartalways --name …

Apache POI及easyExcel读取及写入excel文件

目录 1.excel 2.使用场景 3.Apache POI 4.easyExcel 5.总结 1.excel excel分为两版&#xff0c;03版和07版。 03版的后缀为xls&#xff0c;最大有65536行。 07版的后缀为xlsx&#xff0c;最大行数没有限制。 2.使用场景 将用户信息导出到excel表格中。 将excel中的数…

用pd.DataFrame.to_sql方法插入万行数据耗时21秒

to_sql是Pandas中用于将DataFrame数据写入数据库的方法&#xff0c;可以将DataFrame转换为SQL语句&#xff0c;方便我们将数据存入数据库中&#xff0c;以便进行后续的操作。 to_sql方法中包含多个参数&#xff0c;比较常用的参数有name&#xff08;表名&#xff09;、con&…

【算法挑战】用栈实现队列(含解析、源码)

232.用栈实现队列 https://leetcode-cn.com/problems/implement-queue-using-stacks/ 232.用栈实现队列 题目描述方法 1 思路复杂度代码 方法 2 思路复杂度代码(JavaScript/C) 题目描述 使用栈实现队列的下列操作&#xff1a;push(x) -- 将一个元素放入队列的尾部。 pop(…

系统架构设计师-第15章-面向服务架构设计理论与实践-软考学习笔记

面向服务的体系结构&#xff08;Service-Oriented Architecture, SOA) 面向服务的体系结构&#xff08;Service-Oriented Architecture, SOA&#xff09;是一种软件架构模式&#xff0c;它将应用程序的不同功能组织为一组可重用的、松耦合的、自治的服务&#xff0c;这些服务通…

在前端实现小铃铛上展示消息

点击铃铛显示如下消息框&#xff1a; 如果点击消息&#xff0c;可以实现消息从列表中移除,并从铃铛总数上进行扣减对应的已读消息数。 关于以上功能的实现方式&#xff1a; <!-- 铃铛位置 --><i class"el-icon-bell" click"showPopover true"&…

ubuntu启动报错error: proc_thermal_add, will cont

如题&#xff0c;ubuntu启动报错error: proc_thermal_add, will cont 截图如下&#xff1a; 困扰了我很久&#xff0c;差点就打算重装系统&#xff0c;准备放弃了&#xff0c;但是感谢国外的老哥&#xff0c;写了一篇非常详细的解决方案&#xff0c;我搬过来。 解决方案&#…

03-对象

对象 对象1.对象的创建字面量模式构造函数模式 2.对象的访问3.新增删除对象中的属性4.Object显示类型转换(强制类型转换)ECMAScript中可用的3种强制类型转换如下&#xff1a;Boolean(value)String(value)Number(value)Object类型到Boolean类型Object类型转String类型转换规则&a…

Redis通过复制rdb文件方式同步线上数据到本地以及提示:Can‘t handle RDB format version 9解决

场景 Redis的持久化机制-RDB方式和AOF方式&#xff1a; Redis的持久化机制-RDB方式和AOF方式_rdb 和ao-CSDN博客 Redis持久化机制导致服务自启动后恢复数据过长无法使用以及如何关闭&#xff1a; Redis持久化机制导致服务自启动后恢复数据过长无法使用以及如何关闭_霸道流氓…

mysql数据表设计

命名 mysql表名的命名规范为表名可以用 t_ 、tb_的前缀&#xff0c;或者是业务模块前缀。比如t_order。 有些项目也会使用 tt_、tm_、 ts_ 等前缀&#xff0c;根据项目的习惯命名就好了。 主键&#xff1a; AUTO_INCREMENT 表示自增&#xff0c;UNSIGNED 表示无符号&#xf…

【算法专题】双指针—盛最多水的容器

一、题目解析 分析这个题目不难得出一个容积公式 二、算法原理 解法一&#xff1a;暴力枚举&#xff08;超时&#xff09; 套用上述的容积公式&#xff0c;使用两个for循环来枚举出所有可能的情况&#xff0c;再挑出最大值即可&#xff0c;但是这种写法会超时&#xff0c;导致…

数据结构-初识泛型

写在前&#xff1a; 这一篇博客主要来初步的记录以下泛型的相关内容&#xff0c;内容比较琐碎&#xff0c;就不进行目录的整合&#xff0c;后续可能会对泛型这里进行系统性的梳理&#xff0c;此篇博客主要是对泛型有一个简单的认识与理解&#xff0c;需要知晓的内容。 当我调用…

2. 网络之网络编程

网络编程 文章目录 网络编程1. UDP1.1 DatagramSocket1.1.1 DatagramSocket 构造方法1.1.2 DatagramSocket 方法&#xff1a; 1.2 DatagramPacket1.2.1 DatagramPacket构造方法1.2.2 DaragramPacket方法1.2.3InetSocketAddress API 1.3 UDP回显服务器1.3.1 框架结构1.3.2 读取请…

将图像的锯齿状边缘变得平滑的方法

项目背景 使用PaddleSeg 192x192 模型分割出来的目标有锯齿状边缘&#xff0c;想通过传统算法将这种锯齿状边缘的变得平滑&#xff0c;虽然试了很过方法&#xff0c;但是效果还是不太理想 常用的集中方法 当使用分割算法&#xff08;如分水岭分割、阈值分割等&#xff09;分…