使用OSG显示点云时,如何正确将空白处屏幕坐标转为最接近点云的世界坐标

在OSG中绘制点云,实现画/测点、线等功能时,需要捕捉点云的坐标,但是要在空白区域绘制或测量时,就获取不到点云坐标了。

为了解决这个问题,自己推导出一个将点云空白处屏幕坐标转为最接近点云坐标的算法:

思路是:在每一次捕获真实点云时,即记录下当前点云坐标(lastCloudPoint);空白区域测点时,先将屏幕坐标转为虚拟的世界坐标,然后将坐标投影到 由 eye→center方向(eyeForward)作为法线且经过lastCloudPoint 的虚拟平面上,进而得到最靠近点云的坐标。

实际上,先计算lastCloudPoint 和 tempPt 到eye 的向量,根据两个向量到法线(eyeForward)的长度的比,得到 沿 tempPt 向量方向 由eye 到 虚拟平面的 向量,再加上eye的位置,即为与虚拟平面的交点。

               // 获取屏幕坐标(使用点云的坐标来改正)

		osg::Vec3d screenPt(ea.getX(), ea.getY(), 0);
		osg::Vec3d tempPt = screenPt * inverseVPW;    // 将屏幕坐标转为虚拟的世界坐标

		osg::Vec3d eye, center, up;
		getTransformation(eye, center, up);

		osg::Vec3d eyeForward = center - eye;

		osg::Vec3d dv1 = lastCloudPoint - eye;
		double lenght1 = dv1.length() *
			(eyeForward * dv1 / (eyeForward.length() * dv1.length()));

		osg::Vec3d dv2 = tempPt - eye;
		double lenght2 = dv2.length() *
			(eyeForward * dv2 / (eyeForward.length() * dv2.length()));

		osg::Vec3d dPt = tempPt - eye;
		dPt.x() = dPt.x() * (lenght1 / lenght2);
		dPt.y() = dPt.y() * (lenght1 / lenght2);
		dPt.z() = dPt.z() * (lenght1 / lenght2);

		resPt = eye + dPt;
      osg::Matrixd vwp = camera->getViewMatrix() * camera->getProjectionMatrix() * camera->getViewport()->computeWindowMatrix();	//求得 世界到屏幕的矩阵
	  osg::Matrixd  inverseVPW = osg::Matrixd::inverse(vwp);

  

  

原文地址:https://www.cnblogs.com/xingzhensun/p/11327228.html

时间: 2024-07-30 02:01:26

使用OSG显示点云时,如何正确将空白处屏幕坐标转为最接近点云的世界坐标的相关文章

浅析在项目开发(使用Delegate回调时)如何正确使用ARC

ARC(自动引用计数)是2011年伴随iOS5来的一项技术.简单来说就是通过LLVM3.0编译器帮助程序处理“一大部分”OC中的内存管理.为什么是“一大部分”,这个等会儿解释. 一直以来内存管理这个话题都是初学iOS开发,初学OC语言必须要面对的知识点,也是大家容易出错的地方.对象释放后调用会造成crash.不释放的对象会造成内存泄漏这些问题困扰着初学者.ARC的到来按理说应该是福音,不需要自己管理内存了嘛,多简单.但是随之而来的两个问题:1,我发现周围有些拥有2-5年开发经验的“半老手”(要谦

故障现象:Win7 访问共享时输入正确密码仍然提示密码错误,此帐号在其它机器上可以正常使用,排除帐号密码不对导致的问题。

解决方案一 安装win7的机器日期不对,调整后故障排除. 解决方案二 1.直接按下win+r键,输入secpol.msc,打开本地安全策略.2.找到"安全设置"的"本地策略"的"安全选项"3.在右边一栏找到"网络安全:LAN管理器身份验证级别",双击进入4.在默认状态选项下,英文版应该为"no defined",中文版为空.下拉那个默认选项,选择"仅发送NTLM响应"重启后故障排除. 故

Android 开发时如何正确获取使用扩展存储路径

Android 开发时如何正确获取使用扩展存储路径 先介绍一下Android的存储 在 2.x 版本中,Android设备都是单存储,第三方App写文件,必须申请 WRITE_EXTERNAL_STORAGE 权限: 在4.0之后,Android设备开始有了内置闪存,即 primary storage,并且可以外置SD卡,即 secondary external storage device: WRITE_EXTERNAL_STORAGE 权限变成了仅仅控制 primary storage,同时

路径显示不下时,中间显示省略号

开发环境:VS2012 C# //路径显示不下时,中间显示省略号 class CShowShortPath { public CShowShortPath(string str) { //统一成反斜杠 str = str.Replace('/', '\\'); //收集反斜杆的位置 List<int> indexs = new List<int>(); for (int i = 0; i < str.Length; i++) { if ('\\' == str[i]) { i

解决pyinstaller在单一文件时无法正确添加权限清单问题,(UAC,uac_admin,manifest,asInvoker,python,requireAdministrator)

做了3天的win10的兼容性测试,大部分时间都卡权限获取这了. 以下废话很多,想直接找解决方法,请跳至红字 首先,简单说下uac,自vista后windows再次加严了权限管理,uac (账户控制) ,就是程序对访问一些敏感资源时的限制,当程序需要访问限制资源时会弹窗让用户选择.现在系统主要分两种权限管理员权限和标准权限,当你点击一个程序时只会调用标准权限,这时对windows文件夹,Program文件夹和部分关键的注册表的修改都会报错,访问应该还可以.当你需要安装驱动或者程序时可以使用右键后点

基于51单片机DS18B20测温LCD1602显示可设时设温调时的项目

一.前言 1.基于51单片机DS18B20测温LCD1602显示可设时设温调时的项目包括用Keil软件编写单片机C语言程序和用Proteus软件仿真单片机外围电路 2.基于51单片机DS18B20测温LCD1602显示可设时设温调时的项目构思 (1).声明程序变量思维导图 (2).程序子函数思维导图 (3).程序主函数思维导图 二.基于51单片机DS18B20测温LCD1602显示可设时设温调时的项目的Keil软件编写的单片机C语言程序 1 #include<reg52.h>//声明51单片机

轮值CEO胡厚崑:到2025年所有的企业都将用到云(云的2.0时代,会有几千朵云几万朵云升起来,这将产生不同的技术模式、商业模式、思维模式)

2016年09月04日 07:38 中国经营报 李凡 在全国工商联“2016年中国民营企业500强”排行榜上夺得头把交椅的华为,向外界描绘了面向未来进一步做大做强的路径. 华为创始人任正非于2016年6月在全国科技创新大会上提到,华为下一阶段的目标是,2020年营业收入超过1500亿美元(折合人民币超过1万亿元).华为2015年营收608亿美元,这就意味着,“十三五”期间,华为营收要在2015年的基础上再增长1.5倍. 如何实现这一目标?任正非曾经说过,当前4K/2k/4G和企业.政府对云服务的

广州云栖大会:阿里云携手虎牙,首次落地直播行业边缘节点及云企业网服务

摘要: 阿里云和虎牙直播在直播领域进行了长期的技术合作,特别是在边缘计算节点取得了良好效果,共同建设了边缘节点服务(ENS),落地直播行业"高带宽.高并发.计算密集"的边缘计算节点服务标准. 2018年11月22日,由阿里巴巴集团主办的广东省大数据开发者大会暨2018广东云栖大会在广州正式召开,其中以助力游戏企业畅游全球为主题的游戏云专场也在上午如期举办. 在游戏云专场中,阿里云高级商务专家李知明首先发言:边缘计算节点目前已经是直播行业基础资源供给的重要形态,极大地促进了行业的发展,同

玩客云刷armbian架设nginx php mysql 及可道私有云总结

玩客云刷armbian刷机过程准备硬件:1.玩客云1台2.USB公对公线一根3.USB串口模块一个4.8G以上优盘一个5.拆机螺丝刀,摄子等 工具软件说明:1.USB_Burning_Tool-----------------------刷玩客云通用安卓固件的(需安装)2.USBWriter--------------------------------写入U盘镜像用的(直接用)3.putty_x64_0.70---------------------------PC端调试工具(直接用)4.Ju