【qml-12】Quick3D达成机器人鼠标拖拽转换视角(无限角度)与滚轮缩放

news/2025/9/30 15:36:26/文章来源:https://www.cnblogs.com/wzzkaifa/p/19121264

背景:

还是这个机器人示教器项目,上一篇说到使用WasdController实现的拖拽视角,并不是很完美。此篇记录的是:

可以使用鼠标拖拽,实现视角的无限切换,无论物体现在什么姿态,只管任意拖拽鼠标,直到想要的姿态为止。

可以使用鼠标滚轮缩放物体大小。

可以一键重置。

WasdController:

之所以说这种方式不好,是基于我最初的需求而言。如果想拖拽鼠标转换视角,那它就有bug。

因为WasdController的功能,实际是控制目标节点的相对姿态,假设目标节点是个有生命虫子,它原本的姿态是跟屏幕前的你一样,面朝屏幕深处,背朝屏幕(也就是你),上下左右跟屏幕前的你一样。

所以想象一下,如果是个3d游戏,极品飞车那种室外视角,屏幕里那个车的姿态。使用WasdController时,在屏幕上拖拽上下左右,车头就会随动。

(图片源于网络,如有侵权请告知)

再想象如果让WasdController控制相机,用鼠标在屏幕上拖动上下左右时,很像极品飞车的车内视角,或者cs这类第一视角的游戏画面效果。

(图片源于网络,如有侵权请告知)

(图片源于网络,如有侵权请告知)

而且WasdController还可以支持键盘操作。所以实际上如果你用quick做个3d游戏,真的可以。

只是对于我最初的需求而言不太合适。所以就有了下面新的方法。

在这之前还是要强调一句,非常推荐先做demo,把可能的各种数值做成可以在界面调整的,范围大一些。方便调试。想象一下,只旋转镜头(camera)的话,等于自己扭头,很可能看不见目标物体,所以要调整参数,才知道具体什么效果。

MouseArea:

其实最早想到的就是用这个了,只不过刚好看到WasdController,就想着尽量简单去实现,无奈它不能胜任,所以下面看如何用MouseArea实现。

先回顾一下我曾做过的一个简单版的预览调试界面:

左边滑块按照从上往下说。

1、横向:实际是调整的机器人节点的z轴欧拉旋转,也就是说,无论总体场景的姿态如何,只要左右拖动,机器人即自己左右转。

2、纵向:实际是机器人父级节点的x轴欧拉旋转。

3、camera xyz:很少用,也就一开始用一下看看效果。镜头上下远近动,物体就动(上下左右正好相反)。

4、上条中,本次使用的就是camera的z,控制远近,也就是大小(近大远小)。

5、后面就是机器人关节控制,本次不说了。

最上面的复位:让1、2归零,以及下文实现的机器人相关参数归零。

下面以代码为例说明。

RobotArea.qml:

只取部分节选。

    //定义属性,用于外界输入参数property double _dAngleHorizontal: 0property double _dAngleVertical: 0//让外界知道鼠标拖拽的幅度readonly property double _dX_AngleDraged: _ma._dX_AngleDragedreadonly property double _dY_AngleDraged: _ma._dY_AngleDraged//让外界调用,用于重置姿态function f_ResetPosture(){_ma._rX_prev = 0;_ma._rY_prev = 0;_ma._dX_draged = 0;_ma._dY_draged = 0;_ma._dX_AngleDraged = 0;_ma._dY_AngleDraged = 0;}//让外界知道滚轮变化数值,实际对应相机z轴数值,也就是远近property double _dScale: 0//之前的WasdController不用了// WasdController {//     controlledObject: scene//     xSpeed: -0.1//     ySpeed: -0.1// }MouseArea {id: _maanchors.fill: parentproperty real _rX_prev: 0property real _rY_prev: 0property double _dX_draged: 0property double _dY_draged: 0property double _dX_AngleDraged: 0property double _dY_AngleDraged: 0onPressed: {_rX_prev = mouseX;_rY_prev = mouseY;}onPositionChanged: {let dDraged360 = 360 * 8000 / 720;_dX_draged += mouseX - _rX_prev;if (_dX_draged > dDraged360) { _dX_draged = 0; }if (_dX_draged < -dDraged360) { _dX_draged = 0; }_dY_draged += mouseY - _rY_prev;if (_dY_draged > dDraged360) { _dY_draged = 0; }if (_dY_draged < -dDraged360) { _dY_draged = 0; }_dX_AngleDraged = _dX_draged * 720 / 8000;_dY_AngleDraged = _dY_draged * 720 / 8000;}onWheel: (wheel) => {if (wheel.angleDelta.y > 0){root._dScale++;if (root._dScale > 20) { root._dScale = 20; }}if (wheel.angleDelta.y < 0){root._dScale--;if (root._dScale < -20) { root._dScale = -20; }}}}

我认为代码应该见名知意了。我把MouseArea放在RobotArea里面,算是封装,外界调用时更简洁。逻辑上划分清楚。

数据类型:real和double通用就得了,没影响。

drag值:大于360或小于-360时让它归零,就实现无限翻转了。

滚轮wheel值:往前滚动是120,往后是-120,这个qt设计的不好,计数还得自己搞。这个数对应外界camera的z轴值,我的项目具体情况是,z轴取值正负20,同样要自己试过才知道多大值合适。

main_simple.qml:

最外层的界面。将来集成到项目时,也是参考此界面的代码,可以把RobotArea当做组件用。

    RowLayout {anchors.fill: parentColumnLayout {Layout.fillHeight: true//复位按钮Button {text: "Reset Posture"onClicked: {sldr_horizontal.value = 0;sldr_vertical.value = 0;_robot.f_ResetPosture();_robot._dScale = 0;}}//横向姿态RowLayout {Label { text: "horizontal" }Slider {id:sldr_horizontalfrom: -360to: 360value: 0}}Label { text: sldr_horizontal.value }//纵向姿态RowLayout {Label { text: "vertical" }Slider {id:sldr_verticalfrom: -360to: 360value: 0}}Label { text: sldr_vertical.value }...//远近、大小RowLayout {Label { text: "camera z" }Slider {id:sldr_cmr_zfrom: -20to: 20value: 0}}Label { text: sldr_cmr_z.value }...}RobotArea {id: _robotLayout.fillHeight: trueLayout.fillWidth: true//横纵姿态_dAngleHorizontal: sldr_horizontal.value_dAngleVertical: sldr_vertical.value//远近大小_dCameraZ: sldr_cmr_z.value...//拖拽、滚轮on_DX_AngleDragedChanged: sldr_horizontal.value = _dX_AngleDragedon_DY_AngleDragedChanged: sldr_vertical.value = _dY_AngleDragedon_DScaleChanged: sldr_cmr_z.value = -_dScale}}

以上种种,有些貌似能用属性绑定很简洁,但不行,有些会发生循环绑定。如果用过TabBar和SwipeView组合,一定知道官方代码有

        onCurrentIndexChanged: tabBar.setCurrentIndex(currentIndex)

setCurrentIndex函数就是设置当前索引,但不触发indexChanged信号,很显然就是有些绑定不能让它陷入死循环,要手动控制。这就是这类函数的意义。

效果:

完成上述这些,就可以愉快玩耍了。

左右拖拽:机器人左右转。

上下拖拽:机器人前后翻跟头。

滚轮上下:远缩小,近放大。

任意时候任意角度,可以随便看细节了。

如果不爽,点一下姿态重置按钮,一切从头开始。

本文完。

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

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

相关文章

2025 年挤压造粒机源头厂家最新推荐榜单:前五企业技术实力、服务能力及口碑测评指南对辊挤压/化肥挤压/干粉挤压造粒机厂家推荐

随着有机肥产业朝着规模化、精细化方向快速发展,挤压造粒机作为生产核心设备,其质量与性能直接决定企业生产效率、产品品质及综合成本。但当前市场环境中,设备乱象频发:部分设备无法适配湿度 20%-40% 的发酵有机物…

三生团队网站找谁做的中山市建设工程网上办事系统

因为在OJ上做编程&#xff0c;要求标准输入&#xff0c;特别是多行输入。特意查了资料&#xff0c;自己验证了可行性。if __name__ "__main__":strList []for line in sys.stdin: #当没有接受到输入结束信号就一直遍历每一行tempStr line.split()#对字符串利用空…

2025 年支付宝消费券回收平台最新推荐榜单:优质平台权威测评,助您高效安全处理闲置消费券支付宝消费券回收/闲置支付宝消费券回收/支付宝消费券快速回收平台推荐

随着支付宝消费券在日常生活中的广泛应用,越来越多用户面临消费券闲置难题 —— 指定消费场景限制、有效期短等问题,让大量消费券白白浪费。而当前支付宝消费券回收行业乱象丛生,部分平台结算周期长达数天、安全防护…

ICP备案查询网站 域名备案查询

ICP备案查询网站 域名备案查询ICP备案查询网站 官方查询渠道‌工信部ICP/IP地址/域名信息备案管理系统‌网址:https://beian.miit.gov.cn/https://beian.miit.gov.cn/#/Integrated/index

模板网站哪个好近期十大热点新闻

L1正则化和L2正则化是机器学习中常用的两种正则化方法&#xff0c;用于防止模型过拟合。它们的区别主要体现在数学形式、作用机制和应用效果上。以下是详细对比&#xff1a; 1. 数学定义 L1正则化&#xff08;也叫Lasso正则化&#xff09;&#xff1a; 在损失函数中加入权重参…

网站提交百度了经常修改网站搬瓦工做网站

hello宝子们...我们是艾斯视觉擅长ui设计和前端开发10年经验&#xff01;希望我的分享能帮助到您&#xff01;如需帮助可以评论关注私信我们一起探讨&#xff01;致敬感谢感恩&#xff01; 随着区块链技术和大数据技术的不断发展&#xff0c;两者的结合为企业带来了新的商业模式…

网络与系统攻防技术实验一——逆向破解与Bof

1.实验内容1.1手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。1.2利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。1.3注入一个自己制作的shellcode并运行这段shell…

对外宣传网站建设方案工商营业执照咨询电话24小时

文章目录 第一章 Range &#xff08;单元格&#xff09;对象1. 单元格的引用方法1.1 使用Range 属性1.2 使用Cells 属性1.3 使用快捷记号1.4 使用Offset 属性1.5 使用Resizae 属性1.6 使用Union 方法1.7 使用UsedRange 属性1.8 使用CurrentRegion 属性 2. 选定单元格区域的方法…

做外贸推广的网站建博客网站

记一下idea的svn使用有图超详细 根据在eclipse里使用svn的经验琢磨了一下idea,现把idea下svn的使用方法记录如下 主要分为几个功能来介绍 第一个功能当然是把远程的svn代码拉到我们本地 下面的多出了一个svn的窗口&#xff0c;在左边有加号可以添加一个svn的库 输入svn的地…

“计算机配置\Windows 设置\安全设置\本地策略\审核策略” 配置后不生效

Windows Sever 2016 “计算机配置\Windows 设置\安全设置\本地策略\审核策略” 配置后不生效,gpupdate /force也不生效,重启也不生效,重新打开会恢复未配置。 解决方法: 1、查看审核策略同一目录下面的安全选项”审…

呼和浩特网站建设SEO优化优秀网站网页设计图片

当你在执行一条SQL语句非常慢的时候,你是不是想问Oracle怎么执行这条语句的呢? Oracle提供的SQL_TRACE工具可以让你知道你执行的SQL究竟做了什么.执行的过程会被 输出到trace文件中. 下面用例子来跟踪一个SQL语句的执行情况: SQL> create table t as select rownum as id,o…

云南建设厅网站删除海阳网站开发

11 刷新一下pom 万一没有引入进去 jpa和mybatis选择哪个&#xff1f; 1.看领导要求 2.都会最好 多学点是没错的

Spring Boot 事件发布与监听 观察者模式的实际应用 - 实践

Spring Boot 事件发布与监听 观察者模式的实际应用 - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consola…

[ROI 2018] Quick sort

感觉正常 OI 学生很难在不依赖大脑随机性情况下想出这道题,因为我们没有学斯特林公式。 考虑观察操作的影响,并确定还原策略。这道题中我们可以考虑按 \(1\rightarrow n\) 的顺序还原,这样的好处是如果我们每次能保…

网站后台域名登陆软件临淄招聘信息最新招聘信息

目录 1&#xff0c;下载安装包 2&#xff0c;添加服务器 3&#xff0c;修改服务器配置 3.1 备份配置文件 3.2 修改配置 4&#xff0c;开启samba服务器 5&#xff0c;开关电脑与服务器设置 6&#xff0c; SSH远程登录 1&#xff0c;下载samba服务器安装包 sudo apt in…

上海专业网站建设公司有哪些赣州网站建设

项目源码&#xff1a;https://gitee.com/oklongmm/biye2 引言 随着互联网技术的发展&#xff0c;电子商务得以快速发展&#xff0c;其中之一的在线拍卖系统也逐渐得到了广泛的应用。但是&#xff0c;现有的在线拍卖系统在操作复杂性、安全性和稳定性方面存在一定的问题。为了…

滑动 手机网站 代码ecms dedecms phpcms wordpress

摘要&#xff1a;本文介绍了一种基于深度学习的犬种识别系统系统的代码&#xff0c;采用最先进的YOLOv8算法并对比YOLOv7、YOLOv6、YOLOv5等算法的结果&#xff0c;能够准确识别图像、视频、实时视频流以及批量文件中的犬种。文章详细解释了YOLOv8算法的原理&#xff0c;并提供…

网站优化推广的方法江苏省城市建设信用手册网站

1、StringBuilder类概述 StringBuilder是一个可变的字符串类&#xff0c;主要指的是StringBuilder对象 中的内容是可变的。与之相比String对象的内容是不变的。2、StringBuilder常用构造方法 public StringBuilder() {} //创建空白可变字符串 public StringBuilder(String st…

珠海网站设计哪家好网站做的好坏主要看

前言 本文用于记录系统迁移中遇到的问题及解决方法&#xff0c;如有不对请指出&#xff0c;谢谢&#xff01; 现象 使用DiskGenius进行系统迁移后&#xff0c;使用USB启动失败&#xff0c;反复在品牌logo和黑屏之间切换&#xff0c;期间还会在左上角显示”reset system“报错…

设计师每天都上的网站中小微企业名录库查询

在屋顶、院落或是其他太阳可以照射的地方&#xff0c;安装光伏板&#xff0c;即可实现太阳能发电&#xff0c;也称为光伏发电。这种发电方式是一种干净的可再生的新能源&#xff0c;越来越受到人们的青睐。太阳能发电后&#xff0c;如何将电能储存起来以备随时使用&#xff1f;…