目录

0. 最终效果

1. 为什么是qml+QQuickPaintedItem

2. 屏幕坐标和笛卡尔坐标

3. QPainter的转换矩阵

4. 鼠标位置转换为笛卡尔坐标


0. 最终效果

坐标转换

1. 为什么是qml+QQuickPaintedItem

用过多年的WPF,MFC, 了解OpenGL和Qt Widget,ImGUI, 要做中规中矩的图形软件(效率工具),OpenGL过于复杂,新一点的OpenGL依赖shader编程,不是一般人能轻易驾驭的。MFC也是老黄历了,开发效率低,而且是微软阵营。抛开跨平台不说,WPF应该是功能最为强大的一款,上手简单,效果炫酷,xaml所见即所得无有出其右者。ImGUI是实时架构,多用在游戏界面中,开发理念差别较大。

挑来拣去,qml+QQuickPaintedItem在开发效率、实现效果、运行效率上看是一个不错的组合。

2. 屏幕坐标和笛卡尔坐标

屏幕坐标的原点在左上角,y轴向下,x轴向右。在几何数学上我们一般用笛卡尔坐标,原点在屏幕中央,x轴朝右,y轴朝上。除了原点和轴朝向的不同,这两个坐标的单位也不同,屏幕坐标一般以像素为单位,这个和显示器硬件相关的;在笛卡尔坐标系中,我们用到的是逻辑坐标,比如规定:

  • x轴坐标范围为-3到3, y轴范围为-3到3。

笛卡尔坐标系,来自wikipedia

在屏幕坐标中,一个QQuickPaintedItem的绘制区域假设为:

  • 宽500个像素,高500个像素

屏幕坐标上点(0,0)对应的笛卡尔坐标系上的点(-3,3),在一个图形软件中,图形对象的坐标一般以笛卡尔坐标系作为参考,避免受到显示硬件的影响,这是因为如果采用屏幕坐标,在某个分辨率高的显示器上创建的图形对象在另外一台分辨率低的显示器上就会不正常,采用笛卡尔坐标就不会有这个问题。

有些同学可能要问了,仅仅是采用笛卡尔坐标系就能解决硬件依赖的问题么?毕竟我们什么也没有做啊。这就引入了坐标映射的概念了,用鼠标绘制通常需要进行两次映射,第一次我们得到鼠标事件的位置,这个是屏幕坐标,我们要把这个坐标转换为逻辑坐标,然后图形的变形转换等操作都以逻辑坐标为基础进行操作;第二次是在绘制的时候,我们用QPainter进行绘制,QPainter把绘制指令传递到显卡,并最终到达显示器上依然用的是屏幕坐标(当然中间省略了不少细节),需要我们把逻辑坐标转换为屏幕坐标。

3. QPainter的转换矩阵

我们首先介绍第二次映射,QTransform已经提供了相关的API让我们设置转换矩阵,这个API就是setMatrix函数,目的是设置转换矩阵的参数,官方文档有介绍,有兴趣的自行查看。QTransform这个类功能强大,能进行平移、缩放、错切(shear)等功能,在本文中,需要进行下述转换:

  1. 缩放,(-3,3)比(500,500)小很多,需要放大
  2. 平移,笛卡尔原点在中间,屏幕原点在左上,需要平移
  3. y轴方向颠倒一下

我们已经知道需要哪些转换了,具体如何设置呢?QTransform的是个3x3的矩阵,总共有9个参数,实际上需要设置的参数为5个:m11,m22,m31,m32,m33。m11是x轴的缩放参数;m22是y轴的缩放参数;m31是x轴的平移参数;m32是y轴的平移参数;m33是单位矩阵的值,设为1就行;另外还有一个y轴方向颠倒,我们直接把m22设置好了,前面加个负号就行了。参看下图:

其余四个参数设置为0.0即可。由于所有的绘制操作都要依赖这个矩阵,我们创建一个QTransform类型的成员变量,保存起来,在paint函数中调用setWorldTransform即可:

说了这么多,具体的参数还是举个例子吧,笛卡尔x,y轴范围(-3,3)转换为屏幕x,y范围(0,500)为例,m11为x轴放大系数,值为(500 / 6),m22为-(500 / 6),前面符号是因为两个坐标系下面y轴方向是相反的;m31为x轴平移系数,相当于把笛卡尔原点x坐标0移到视口最左边,距离为500除以2,为250。m32也是250:

4. 鼠标位置转换为笛卡尔坐标

上面第三节写的是绘制的坐标转换,其实还有个鼠标位置的转换,相当于上面的逆转换,即,鼠标的x坐标缩小(500/6.0)倍,y缩小-(500/6.0)倍,水平方向平移-3, 垂直方向平移3即可。这些操作在QQuickPaintedItem派生类的鼠标回调函数开始处进行即可,如mousePressEvent,mouseMoveEvent等等。

专业图形软件一般在界面实时显示鼠标位置,这个通过qml即可以实现,首先导出QQuickPaintedItem派生类到qml中,假设在qml中类型为DrawingArea,我们定义一个MouseArea,在onMouseXChanged和onMouseYChanged事件处理函数中获取鼠标位置(当然要进行转换),然后定义两个TextInput(id分别为xpos和ypos),分别展示x和y鼠标位置。

实时展示的TextInput如下所示:

效果见文章开始处的视频。

qml+QQuickPaintedItem笛卡尔坐标和屏幕坐标的转换相关推荐

  1. OpenGL: 3D坐标到屏幕坐标的转换逻辑(gluProject的实现)(转)

    OpenGL: 3D坐标到屏幕坐标的转换逻辑(gluProject的实现) 遇到需要将3D坐标转换到屏幕坐标的问题,在网上很多朋友也在寻找答案,下面是glu中gluProject函数的实现.(实际上就 ...

  2. 屏幕距离和坐便转换工具_地图经纬度坐标与屏幕坐标的转换(android版)

    我们在开发GIS系统的时候,首先要解决的就是地图的可视化问题,这个问题的关键就在于如何把地图的坐标转换成屏幕坐标,然后才到渲染着色.标注等.以下以wgs84经纬度坐标为基准,介绍一下地图经纬度坐标与屏 ...

  3. TrackPopupMenu参数为屏幕坐标的转换

    第一次接触TrackPopupMenu函数的时候大家可能会发现:编写出来的窗口的动态弹出菜单位置始终不能如愿地显示在正确位置,仔细观察或者查MSDN就知道,TrackPopupMenu函数中的坐标参数 ...

  4. c语言创意图案设计图片大全,《C语言图形设计》刘振安,苏仕华编.pdf

    <C语言图形设计>刘振安,苏仕华编C语言图形设计 [General Information] 书名=C语言图形设计 作者=刘振安,苏仕华编著 页数=231 出版社=北京市:人民邮电出版社 ...

  5. QML中用javascript 实现中文转换拼音

    项目需要, 今天整理了一下.在QML调用javascrit将中文汉字转换成拼音. 感觉执行效率低. 下面是主要代码. 具体代码请参考QMLPinyin import "./pinyinjs/ ...

  6. 三维坐标系介绍与转换

    转载自:http://support.supermap.com.cn/DataWarehouse/WebDocHelp/OnlineHelp/Flash3D/G_ProjectDocumentatio ...

  7. unity 坐标系转换_Unity的几种坐标系及相互转换

    介绍 1.WorldSpace(世界坐标系) 当我们向场景中添加物体时,他们都是以世界坐标系的方式的方式显示在场景中的 通过transform.position可以得到它在世界中的坐标位置,trans ...

  8. D3D坐标系统下3D世界坐标映射到2D屏幕坐标的平移矩阵

    D3D坐标系统下3D世界坐标映射到2D屏幕坐标的平移矩阵,有需要的朋友可以参考下. D3D中绘画3D模型基本上就是靠3个矩阵World, View, Projection来联合进行模型位置定位.视角定 ...

  9. Qt Quick QML

    Qt Quick简介 Qt Quick是一个用于帮助开发者设计直观,现代,流畅的用户界面的技术集,近年来被广泛应用于手机,媒体播放器,机顶盒和其他手提设备.Qt Quick中包含了大量的用户界面元素, ...

最新文章

  1. MathType6.9b安装及在Word2013中无法正常使用的解决方法
  2. C++ 单例模式析构函数的运用,析构函数的线程安全
  3. spoj 375 Query on a tree
  4. andriod访问网络出现NetworkOnMainThreadException解决方法
  5. 【鲲鹏来了】手把手教你创造一个属于自己的鲲鹏开发者环境
  6. 【Spring】配置SpringBoot同时支持http和https访问
  7. linuxcentos防ssh爆破
  8. 学习戴铭博文《从 ReactiveCocoa 中能学到什么?不用此库也能学以致用》的总结...
  9. 5分钟搞懂如何在Spring Boot中Schedule Tasks
  10. CS,四,组网及因特网
  11. 3dfier:GIS数据转3D城市模型
  12. python中count什么意思_python中函数COUNT()的功能是什么
  13. web安全攻防渗透+赵雨佳43
  14. 如何通过织云Lite愉快地玩转TSW
  15. 云上城之歌通用服务器是什么意思,云上城之歌ios安卓是互通的吗 不同系统可以一起玩吗...
  16. 关于bootstrap--表格(table的各种样式)
  17. python台风动图绘制_python可视化绘图:台风路径可视化
  18. 活用async/await,实现一些让Vue更好用的装饰器
  19. 如何判断Android手机是否黑屏和锁屏
  20. 安天每日安全简讯20160712

热门文章

  1. clearInterval() 函数详解
  2. python 逗号作用
  3. 作为通信人,你知道国内有哪些通信领域的博物馆吗?
  4. Tcl字符串命令string
  5. 读书笔记:20220729 TRC2013 Max pressure control of a network of signalized intersections
  6. dcs中标准计算机柜有哪些,电气PC,MCC,DCS分别代表什么?
  7. 基于jsp的塞北村镇旅游网站的设计与实现--【毕业论文】
  8. 我是怎样阅读技术论文的
  9. python数据分析与挖掘实战(航空公司客户价值分析)
  10. PDF压缩(全图片PDF压缩)