我们在对 QGraphicsItem 进行变换时,QT 提供了很多便捷的方法。但当我们想获取当前变换的角度时却有些困难,因为 QTransform 没有提供获取角度的方法。在文章Qt 从 QTransform 逆向解出 Translate/Scale/Rotate(平移/缩放/旋转)分析分析过,使用 QTransform 进行多种变换组合后,由于组合顺序不能预知、组合数量不能预知,很难从 QTransform 矩阵中推算出当前变换的角度。即使推算出来,由于切变、缩放等变换的影响,推算出的角度也不准确。结合 QLineF 可以有个简便的方式来倒推变换角度。

一、从 QGraphicsItem 的变换说起

对 QGraphicsItem 进行变换有三种方式:

1. 使用 setRotation() 或 setScale();

2. 使用 setTransform();

3. 使用 setTransformations();

如果同时使用多种方式,变换效果将进行叠加。变换按照固定的顺序进行:

  • 第一步:应用 transform() 指定的变换;
  • 第二步:应用 transformations() 指定的变换;
  • 第三步:应用 rotation(), transformOriginPoint() 指定的变换;
  • 第四步:应用 scale(), transformOriginPoint() 指定的变换;

如果 transform() 中指定旋转角度 A,rotation() 指定旋转角度 B,那么 QGraphicsItem 旋转的角度就是 A + B。然后使用 resetTransform() 复位 transform(),那么 QGraphicsItem 旋转的角度就是 B 。也就是说三种变换方式数值的变换相互不影响。

对于有父子关系的 QGraphicsItem 父项目的变换将累加到子项目,子项目通过方法 sceneTransform() 获取所有累加的变换,通过 scenePos() 获取子项目在 scene 上的坐标。

二、解析 QGraphicsItem 当前旋转的角度

  1. 直接作用于 QGraphicsItem 的角度

不考虑父节项目对 QGraphicsItem 的影响,或者 QGraphicsItem 没有父项目时,计算 QGraphicsItem 当前旋转的角度,需要分别考虑 setRotation()、setTransform() 和 setTransformations() 设置的角度,分别计算后再进行累加即可。如果 QGraphicsItem 没有父项目,可以使用 sceneTransform() 获取所有累加变换后的 transform,从 transform 推算角度。

  1. 有父项目的 QGraphicsItem 的角度

考虑父项目对 QGraphicsItem 的变换影响,直接使用 sceneTransform() 获取所有累加变换后的 transform,再推算角度。

三、使用 QLineF 从 transform 提取角度

QLineF 提供的方法 angleTo() 可以帮助我们方便的计算2条直线间的夹角。要从 transform 中计算角度,可以先构建一条直线,然后使用 QTransform 的 map() 方法对直线进行变换。变换后的直线与原直线间的夹角就是 transform 旋转的角度。示例代码如下:

QTransform trans = item->sceneTransform();
QLineF line1{{0,0},{1,0}};
QLineF line2 = trans.map(line1);
qreal angle = line2.angleTo(line1)

注意:如果 transform 中执行过 shear 变换,该方法推算出来的角度不是原来设置的角度。

巧用 QLineF 从 QTransform 提取角度的更多相关文章

  1. Unity3D脚本中文系列教程(十三)

    http://dong2008hong.blog.163.com/blog/static/469688272014032334486/ Unity3D脚本中文系列教程(十二) ◆ function G ...

  2. SICK激光雷达LMS511测量数据说明

    帧结构说明 LMS511的官方手册存在几个版本,在<Laser Measurement Systems of the LMS500 Product Family>的英文手册中,对单次(连续 ...

  3. Image Processing and Computer Vision_Review:Local Invariant Feature Detectors: A Survey——2007.11

    翻译 局部不变特征探测器:一项调查 摘要 -在本次调查中,我们概述了不变兴趣点探测器,它们如何随着时间的推移而发展,它们如何工作,以及它们各自的优点和缺点.我们首先定义理想局部特征检测器的属性.接下来 ...

  4. [OpenCV实战]6 基于特征点匹配的视频稳像

    目录 1 介绍 1.1 视频稳定的方法 1.2 使用点特征匹配的视频稳定 2 算法 2.1 帧间运动信息获取 2.1.1 合适的特征点获取 2.1.2 Lucas-Kanade光流法 2.1.3 运动 ...

  5. CSharpGL(32)矩阵与四元数与角度旋转轴的相互转换

    CSharpGL(32)矩阵与四元数与角度旋转轴的相互转换 三维世界里的旋转(rotate),可以用一个3x3的矩阵描述:可以用(旋转角度float+旋转轴vec3)描述.数学家欧拉证明了这两种形式可 ...

  6. 卷积神经网络提取特征并用于SVM

    模式识别课程的一次作业.其目标是对UCI的手写数字数据集进行识别,样本数量大约是1600个.图片大小为16x16.要求必须使用SVM作为二分类的分类器. 本文重点是如何使用卷积神经网络(CNN)来提取 ...

  7. [从产品角度学EXCEL 02]-EXCEL里的树形结构

    这是<从产品角度学EXCEL>系列第三篇. 前言请看: 0 为什么要关注EXCEL的本质 1 excel是怎样运作的 或者你可以去微信公众号@尾巴说数 获得连载目录. 本文仅由尾巴本人发布 ...

  8. 前端工程师技能之photoshop巧用系列第三篇——切图篇

    × 目录 [1]切图信息 [2]切图步骤 [3]实战 前面的话 前端工程师除了使用photoshop进行测量之外,更重要的是要使用该软件进行切图.本文是photoshop巧用系列的第三篇——切图篇 切 ...

  9. TF-IDF提取行业关键词

    1. TF-IDF简介 TF-IDF(Term Frequency/Inverse Document Frequency)是信息检索领域非常重要的搜索词重要性度量:用以衡量一个关键词\(w\)对于查询 ...

  10. MyBatis的getMapper()接口、resultMap标签、Alias别名、 尽量提取sql列、动态操作

    一.getMapper()接口 解析:getMapper()接口 IDept.class定义一个接口, 挂载一个没有实现的方法,特殊之处,借楼任何方法,必须和小配置中id属性是一致的 通过代理:生成接 ...

随机推荐

  1. Dockerfile-NGINX镜像制作

    1 NGINX镜像制作: 1.1 NGINX-dockerfile FROM centos:7 LABEL maintainer www.chenleilei.net RUN useradd www ...

  2. LeetCode 208. Implement Trie (Prefix Tree) 实现 Trie (前缀树)(C++/Java)

    题目: Implement a trie with insert, search, and startsWith methods. Example: Trie trie = new Trie(); t ...

  3. Easysearch 内核完善之 OOM 内存溢出优化案例一则

    最近某客户在使用 Easysearch 做聚合时,报出 OOM 导致掉节点的问题,当时直接让客户试着调整 indices.breaker.request.limit ,但是不起作用,于是又看了下 Ea ...

  4. 在.NET Core,除了VB的LikeString,还有其它方法吗?(四种LikeString实现分享)

    Like运算符很好用,特别是它所提供的其中*.?这两种通配符,在Windows文件系统和各类项目中运用非常广泛. 但Like运算符仅在VB中支持,在C#中,如何实现呢? 以下是关于LikeString ...

  5. flutter 创建第一个项目(二)

    新建flutter project 项目 这样就创建出了第一个项目

  6. 在线RSA签名工具

    在线RSA签名工具支持多种RSA签名算法,包括RSA-MD5.RSA-SHA1.RSA-SHA224.RSA-SHA256.RSA-SHA384和RSA-SHA512.用户只需上传需要签名的数据和私钥 ...

  7. XTuner大模型单卡低成本微调实战

    Smiling & Weeping ---- 有趣是片难寻的土,灵魂是朵难养的花 一些关于的模型训练的小tips: 1.ctrl+c中断  2.tmux new -s 名称   3.ctrl+ ...

  8. 有点儿神奇,原来vue3的setup语法糖中组件无需注册因为这个

    前言 众所周知,在vue2的时候使用一个vue组件要么全局注册,要么局部注册.但是在setup语法糖中直接将组件import导入无需注册就可以使用,你知道这是为什么呢?注:本文中使用的vue版本为3. ...

  9. Ansible的常用模块

    目录 ansible常用模块 1. file模块 1.1 file模块的选项 1.2 file模块的使用 1.2.1 使用file模块在远程主机创建文件 1.2.2 创建目录 1.2.3 删除文件/目 ...

  10. MySQL bit类型增加索引后查询结果不正确案例浅析

    昨天同事遇到的一个案例,这里简单描述一下:一个表里面有一个bit类型的字段,同事在优化相关SQL的过程中,给这个表的bit类型的字段新增了一个索引,然后测试验证 时,居然发现SQL语句执行结果跟不加索 ...