zoukankan      html  css  js  c++  java
  • 使用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);
    

      

      

  • 相关阅读:
    ubuntu下安装oracle
    网站框架策划时的小技巧--页面原型篇
    中国电商价格欺诈何时休?
    系统升级日记(4):如何快速的修改Infopath中的各种URL
    系统升级日记(3)- 升级SharePoint解决方案和Infopath
    系统升级日记(2)- 升级到SharePoint Server 2013
    系统升级日记(1)- 升级到SQL Server 2012
    【译】《C# Tips -- Write Better C#》
    [.NET] 一步步打造一个简单的 MVC 电商网站
    反骨仔的 2016 年度全文目录索引
  • 原文地址:https://www.cnblogs.com/xingzhensun/p/11327228.html
Copyright © 2011-2022 走看看