查看: 1409|回复: 9

关于OSG坐标转换的问题

[复制链接]

该用户从未签到

发表于 2017-10-24 22:55:02 | 显示全部楼层 |阅读模式

请问一下,把二维的平面坐标怎么能转化为经纬度显示出来,并且在不同的比例尺下显示不同的高度,当鼠标没有移动到地球时,不显示(地球已经有WGS-84坐标系)
直接调用convertXYZToLatLongHeight()不对啊
m_csn->setEllipsoidModel(new osg::EllipsoidModel());
QQ图片20171024225211.jpg

该用户从未签到

发表于 2017-10-27 10:14:27 | 显示全部楼层
love灬油油 发表于 2017-10-26 23:11
好的,谢谢您,我去找找二维屏幕坐标转换成三维世界坐标的先关接口~~,您知道接口叫什么吗?

这个没有接口,你乘以一个逆MVPW矩阵就可以了,可以参考我这个http://blog.csdn.net/a819721810/article/details/77965598

该用户从未签到

发表于 2017-10-26 14:41:28 | 显示全部楼层
把二维屏幕坐标转换成三维世界坐标,再换算成经纬度即可

该用户从未签到

 楼主| 发表于 2017-10-26 23:11:00 | 显示全部楼层
sy2178668 发表于 2017-10-26 14:41
把二维屏幕坐标转换成三维世界坐标,再换算成经纬度即可

好的,谢谢您,我去找找二维屏幕坐标转换成三维世界坐标的先关接口~~,您知道接口叫什么吗?

该用户从未签到

 楼主| 发表于 2017-10-27 14:30:34 | 显示全部楼层
SunburstRun 发表于 2017-10-27 10:14
这个没有接口,你乘以一个逆MVPW矩阵就可以了,可以参考我这个http://blog.csdn.net/a819721810/article/ ...

好的,我去看看

该用户从未签到

 楼主| 发表于 2017-10-28 22:56:19 | 显示全部楼层
SunburstRun 发表于 2017-10-27 10:14
这个没有接口,你乘以一个逆MVPW矩阵就可以了,可以参考我这个http://blog.csdn.net/a819721810/article/ ...

这个逆MVPW矩阵,我已经参考你的做好了,但是关于这个viewer的获取(这里注意几个问题,viewer一定要是viewer->run()之后的viewer,你可以设置事件回调),我还有些问题,关于这个viewer的回调,您能给我写参考吗?谢谢

该用户从未签到

发表于 2017-10-30 09:26:12 | 显示全部楼层
love灬油油 发表于 2017-10-28 22:56
这个逆MVPW矩阵,我已经参考你的做好了,但是关于这个viewer的获取(这里注意几个问题,viewer一定要是vi ...

#include "stdafx.h"
#include<Windows.h>
#include<osgDB/ReadFile>
#include<osgDB/WriteFile>
#include<osgViewer/Viewer>
#include<osg/Node>
#include<osg/Geode>
#include<osg/Group>
#include<osg/Texture2D>
#include<osg/MatrixTransform>
#include<osgSim/Impostor>
#include<osg/NodeCallback>
#include<osgUtil/Optimizer>
#include <osg/TexEnv>
#include <osg/Geometry>
#include <osg/TexGen>
#include<osgViewer//Viewer>
#include<osgViewer/ViewerEventHandlers>
#include<osgViewer/CompositeViewer>
#include<osgUtil/SmoothingVisitor>
#include <osgUtil/SceneView>
#include<map>
#include <osg/MatrixTransform>
#include<osgGA/TrackballManipulator>
#pragma comment(lib,"osgd.lib")
#pragma comment(lib,"osgViewerd.lib")
#pragma comment(lib,"osgGAd.lib")
#pragma comment(lib,"osgDBd.lib")
#pragma comment(lib,"osgFXd.lib")
#pragma comment(lib,"osgUtild.lib")
osg::Vec3d world2Screen(osg::ref_ptr<osgViewer::Viewer> viewer, osg::Vec3 worldPoint);
osg::Vec3d screen2World(osg::ref_ptr<osgViewer::Viewer> viewer, osg::Vec3 screenPoint);
osg::ref_ptr<osg::Image> image = new osg::Image;
class CaptureCallback :public osg::Camera:rawCallback
{
public:
        CaptureCallback(){}
        CaptureCallback(osg::ref_ptr<osg::Image> image) :_image(image)
        {

        }
        ~CaptureCallback() {}

        virtual void operator()(const osg::Camera &camera) const
        {
                //得到窗口系统接口
                osg::ref_ptr<osg::GraphicsContext::WindowingSystemInterface> wsi = osg::GraphicsContext::getWindowingSystemInterface();
                unsigned int width, height;
                //得到分辨率
                wsi->getScreenResolution(osg::GraphicsContext::ScreenIdentifier(0), width, height);

                //读取像素信息抓图
                _image->readPixels(448, 28, 1024, 1024, GL_RGB, GL_UNSIGNED_BYTE);
        }

private:
        osg::ref_ptr<osg::Image> _image;

};

class ReplaceGeometryAndGetScreenCoord :public osgGA::GUIEventHandler
{
public:
        ReplaceGeometryAndGetScreenCoord(osg::ref_ptr<osgGA::TrackballManipulator> &track, osg::ref_ptr<osg::Group> &root, osg::Vec3* arr) :_track(track), _root(root), _arr(arr)
        {

        }
        ReplaceGeometryAndGetScreenCoord(osg::ref_ptr<osgGA::TrackballManipulator> &track, osg::ref_ptr<osg::Group> &root, osg::Vec3 point0, osg::Vec3 point1) :_track(track), _root(root), _point0(point0), _point1(point1)
        {

        }
        ReplaceGeometryAndGetScreenCoord(osg::ref_ptr<osg::Group> &root, osg::Vec3 point0, osg::Vec3 point1) :_root(root), _point0(point0), _point1(point1)
        {

        }
        ReplaceGeometryAndGetScreenCoord(osg::ref_ptr<osg::Geode> &geode, osg::ref_ptr<osg::Group> &root, osg::Vec3 point0, osg::Vec3 point1) :_geode(geode), _root(root), _point0(point0), _point1(point1)
        {

        }
        bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
        {
                osg::ref_ptr<osgViewer::Viewer> viewer = dynamic_cast<osgViewer::Viewer *>(&aa);
                if (viewer == NULL)
                {
                        return false;
                }
                static osg::Vec3d eye, center, up;
                _track->getHomePosition(eye, center, up);
                static osg::Vec3 cin[6], cout[6];
                static osg::ref_ptr<osg::Geode> geodeStraightLine = new osg::Geode;
                static osg::ref_ptr<osg::Geode> geodeTexture = new osg::Geode;
                static bool flag = true;
                static osg::ref_ptr<osg::Image>getImage;
                switch (ea.getEventType())
                {
                case osgGA::GUIEventAdapter::KEYDOWN:
                {
                        if (ea.getKey() == osgGA::GUIEventAdapter::KEY_3)
                        {
                                osg::ref_ptr<osg::Vec3Array> vertexTexture = new osg::Vec3Array;
                                osg::ref_ptr<osg::Vec4Array> colorTexture = new osg::Vec4Array;
                                osg::ref_ptr<osg::Vec3Array> ncTexture = new osg::Vec3Array;
                                osg::ref_ptr<osg::Geometry> geometyrTexture = new osg::Geometry;
                                osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D;
                                osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet;
                                osg::ref_ptr<osg::Vec2Array> vt = new osg::Vec2Array;
                                getImage = osgDB::readImageFile("ScreenShot1.jpg");
                                vt->push_back(osg::Vec2(0.0f, 0.0f));
                                vt->push_back(osg::Vec2(1.0f, 0.0f));
                                vt->push_back(osg::Vec2(1.0f, 1.0f));
                                vt->push_back(osg::Vec2(0.0f, 1.0f));
                                geometyrTexture->setTexCoordArray(0, vt);

                                //colorTexture->push_back(osg::Vec4(0, 0, 0, 1));
                                texture->setImage(getImage.get());
                                ncTexture->push_back(osg::Vec3(0.0f, -1.0f, 0.0f));
                                stateset->setTextureAttributeAndModes(0, texture.get(), osg::StateAttribute::ON);
                                vertexTexture->push_back(cout[0]);
                                vertexTexture->push_back(cout[1]);
                                vertexTexture->push_back(cout[2]);
                                vertexTexture->push_back(cout[3]);

                                geometyrTexture->setVertexArray(vertexTexture);
                                geometyrTexture->setNormalArray(ncTexture);
                                geometyrTexture->setNormalBinding(osg::Geometry::BIND_OVERALL);
                                geometyrTexture->addPrimitiveSet(new osg::DrawArrays(osg:rimitiveSet:UADS, 0, vertexTexture->size()));
                                geodeTexture->setStateSet(stateset);
                                geodeTexture->addDrawable(geometyrTexture);
                                _root->addChild(geodeTexture);
                        }
                        if (ea.getKey() == osgGA::GUIEventAdapter::KEY_1)
                        {

                                cin[0] = world2Screen(viewer, _arr[0]);
                                cin[1] = world2Screen(viewer, _arr[1]);
                                cin[2] = world2Screen(viewer, _arr[2]);
                                cin[3] = world2Screen(viewer, _arr[3]);
                                cin[4] = world2Screen(viewer, _arr[4]);
                                cin[5] = world2Screen(viewer, _arr[5]);

                                printf("cin[0]: %f,%f,%f\n", cin[0]._v[0], cin[0]._v[1], cin[0]._v[2]);
                                printf("cin[1]: %f,%f,%f\n", cin[1]._v[0], cin[1]._v[1], cin[1]._v[2]);
                                printf("cin[2]: %f,%f,%f\n", cin[2]._v[0], cin[2]._v[1], cin[2]._v[2]);
                                printf("cin[3]: %f,%f,%f\n", cin[3]._v[0], cin[3]._v[1], cin[3]._v[2]);
                                printf("cin[4]: %f,%f,%f\n", cin[4]._v[0], cin[4]._v[1], cin[4]._v[2]);
                                printf("cin[5]: %f,%f,%f\n", cin[5]._v[0], cin[5]._v[1], cin[5]._v[2]);
                                std::cout << std::endl;
                                char filename[128];
                                sprintf(filename, "ScreenShot%d.jpg", 1);
                                osgDB::writeImageFile(*(image), filename);
                               
                        }
                        if (ea.getKey() == osgGA::GUIEventAdapter::KEY_2)
                        {
                                cout[0] = screen2World(viewer, osg::Vec3(448, 28, cin[4]._v[2]));
                                cout[1] = screen2World(viewer, osg::Vec3(1472, 28, cin[4]._v[2]));
                                cout[2] = screen2World(viewer, osg::Vec3(1472, 1052, cin[4]._v[2]));
                                cout[3] = screen2World(viewer, osg::Vec3(448, 1052, cin[4]._v[2]));
                                printf("cout[0]: %f,%f,%f\n", cout[0]._v[0], cout[0]._v[1], cout[0]._v[2]);
                                printf("cout[1]: %f,%f,%f\n", cout[1]._v[0], cout[1]._v[1], cout[1]._v[2]);
                                printf("cout[2]: %f,%f,%f\n", cout[2]._v[0], cout[2]._v[1], cout[2]._v[2]);
                                printf("cout[3]: %f,%f,%f\n", cout[3]._v[0], cout[3]._v[1], cout[3]._v[2]);
                               
                        }
                        if (ea.getKey() == osgGA::GUIEventAdapter::KEY_F10)
                        {
                                cout[0] = screen2World(viewer, osg::Vec3(cin[0]._v[0], cin[0]._v[1], cin[4]._v[2]));
                                cout[1] = screen2World(viewer, osg::Vec3(cin[1]._v[0], cin[1]._v[1], cin[4]._v[2]));
                                cout[2] = screen2World(viewer, osg::Vec3(cin[2]._v[0], cin[2]._v[1], cin[4]._v[2]));
                                cout[3] = screen2World(viewer, osg::Vec3(cin[3]._v[0], cin[3]._v[1], cin[4]._v[2]));
                                cout[4] = screen2World(viewer, osg::Vec3(cin[4]._v[0], cin[4]._v[1], cin[4]._v[2]));
                                cout[5] = screen2World(viewer, osg::Vec3(cin[5]._v[0], cin[5]._v[1], cin[4]._v[2]));
                                printf("cout[0]: %f,%f,%f\n", cout[0]._v[0], cout[0]._v[1], cout[0]._v[2]);
                                printf("cout[1]: %f,%f,%f\n", cout[1]._v[0], cout[1]._v[1], cout[1]._v[2]);
                                printf("cout[2]: %f,%f,%f\n", cout[2]._v[0], cout[2]._v[1], cout[2]._v[2]);
                                printf("cout[3]: %f,%f,%f\n", cout[3]._v[0], cout[3]._v[1], cout[3]._v[2]);
                                printf("cout[4]: %f,%f,%f\n", cout[4]._v[0], cout[4]._v[1], cout[4]._v[2]);
                                printf("cout[5]: %f,%f,%f\n", cout[5]._v[0], cout[5]._v[1], cout[5]._v[2]);
                                std::cout << std::endl;
                       
                        }
                        if (ea.getKey() == osgGA::GUIEventAdapter::KEY_F11)
                        {
                                osg::ref_ptr<osg::Vec3Array> vertexStraightLine = new osg::Vec3Array;
                                osg::ref_ptr < osg::Vec4Array> colorStraightLine = new osg::Vec4Array;
                                osg::ref_ptr<osg::Vec3Array> ncStraightLine = new osg::Vec3Array;
                                osg::ref_ptr<osg::Geometry> geometyrStraightLine = new osg::Geometry;

                                ncStraightLine->push_back(osg::Vec3(0.0f, -1.0f, 0.0f));
                                vertexStraightLine->push_back(cout[0]);
                                vertexStraightLine->push_back(cout[1]);
                                vertexStraightLine->push_back(cout[2]);
                                vertexStraightLine->push_back(cout[3]);
                                vertexStraightLine->push_back(cout[4]);
                                vertexStraightLine->push_back(cout[5]);
                                colorStraightLine->push_back(osg::Vec4(1, 0, 0, 1));

                                geometyrStraightLine->setVertexArray(vertexStraightLine);
                                geometyrStraightLine->setColorArray(colorStraightLine);
                                geometyrStraightLine->setNormalArray(ncStraightLine);

                                geometyrStraightLine->setColorBinding(osg::Geometry::BIND_OVERALL);
                                geometyrStraightLine->setNormalBinding(osg::Geometry::BIND_OVERALL);
                                geometyrStraightLine->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet:INES, 0, vertexStraightLine->size()));
                                geodeStraightLine->addDrawable(geometyrStraightLine);
                                _root->addChild(geodeStraightLine);

                        }
                        if (ea.getKey() == osgGA::GUIEventAdapter::KEY_0)
                        {
                                if (flag&&geodeTexture)
                                {
                                        _root->removeChild(geodeTexture);
                                        flag = false;
                                }
                                else
                                {
                                        _root->addChild(geodeTexture);
                                        flag = true;
                                }
                        }
                        if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Space)
                        {
                                _track->setTransformation(eye, center, up);
                        }
                }
                break;
                default:
                        return false;//一定设为false不然不能旋转
                }
                return true;
        }
        osg::Vec3 _point0, _point1;
        osg::ref_ptr<osg::Group>& _root;
        osg::ref_ptr<osg::Geode> _geode;
        osg::ref_ptr<osgGA::TrackballManipulator> _track;
        osg::Vec3 *_arr;
};

osg::Vec3d screen2World(osg::ref_ptr<osgViewer::Viewer> viewer, osg::Vec3 screenPoint)//将屏幕坐标转换到世界坐标
{
        osg::Vec3d vec3;
        osg::ref_ptr<osg::Camera> camera = viewer->getCamera();
        //osg::Vec3d vScreen(x,y, 0);
        osg::Matrix mVPW = camera->getViewMatrix() * camera->getProjectionMatrix() * camera->getViewport()->computeWindowMatrix();
        osg::Matrix invertVPW;
        invertVPW.invert(mVPW);
        vec3 = screenPoint * invertVPW;
        return vec3;
}

osg::Vec3d world2Screen(osg::ref_ptr<osgViewer::Viewer> viewer, osg::Vec3 worldPoint)//世界到屏幕
{
        osg::Vec3d vec3;
        osg::ref_ptr<osg::Camera> camera = viewer->getCamera();
        osg::Matrix mVPW = camera->getViewMatrix() * camera->getProjectionMatrix() * camera->getViewport()->computeWindowMatrix();
        vec3 = worldPoint * mVPW;
        return vec3;
}

int main()
{
        osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
        osg::ref_ptr<osg::Group> root = new osg::Group;
        osg::ref_ptr<osg::Node>Nnode = osgDB::readNodeFile("E://迅雷下载//OpenSceneGraph-Data-3.0.0//ceep.ive");

        osg::ref_ptr<osg::Geometry> geometyrObliqueLine = new osg::Geometry;
        osg::ref_ptr<osg::Vec3Array> vertexObliqueLine = new osg::Vec3Array;
        osg::ref_ptr < osg::Vec4Array> colorObliqueLine = new osg::Vec4Array;
        osg::ref_ptr<osg::Vec3Array> ncObliqueLine = new osg::Vec3Array;
        osg::ref_ptr<osg::Geode> geodeObliqueLine = new osg::Geode;

        osg::Vec3 arr[6];
        arr[0].set(100, 105, 100);
        arr[1].set(120, 120, 100);

        arr[2].set(120, 100, 95);
        arr[3].set(100, 120, 95);

        arr[4].set(100, 95, 105);
        arr[5].set(120, 130, 105);
        ncObliqueLine->push_back(osg::Vec3(0.0f, -1.0f, 0.0f));
        vertexObliqueLine->push_back(arr[0]);
        vertexObliqueLine->push_back(arr[1]);

        vertexObliqueLine->push_back(arr[2]);
        vertexObliqueLine->push_back(arr[3]);

        vertexObliqueLine->push_back(arr[4]);
        vertexObliqueLine->push_back(arr[5]);
        colorObliqueLine->push_back(osg::Vec4(0, 1, 0, 1));

        geometyrObliqueLine->setVertexArray(vertexObliqueLine);
        geometyrObliqueLine->setColorArray(colorObliqueLine);
        geometyrObliqueLine->setNormalArray(ncObliqueLine);

        geometyrObliqueLine->setColorBinding(osg::Geometry::BIND_OVERALL);
        geometyrObliqueLine->setNormalBinding(osg::Geometry::BIND_OVERALL);

        geometyrObliqueLine->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES, 0, vertexObliqueLine->size()));

        geodeObliqueLine->addDrawable(geometyrObliqueLine);


        root->addChild(geodeObliqueLine);
        //        root->addChild(Nnode);
        viewer->getCamera()->setPostDrawCallback(new CaptureCallback(image));
        osg::ref_ptr<osgGA::TrackballManipulator> track = new osgGA::TrackballManipulator;
        viewer->setCameraManipulator(track); //设置视点的操作类,类似Vega Prime的MotionDrive

        viewer->setSceneData(root.get());

        viewer->realize();
       
        viewer->addEventHandler(new ReplaceGeometryAndGetScreenCoord(track, root, arr));

        viewer->addEventHandler(new osgViewer::StatsHandler);//显示帧事件

        //point0 = world2Screen(viewer, vertexStraightLine[0][0]);
        //point1 = world2Screen(viewer, vertexStraightLine[0][1]);

        //printf("point0: %f,%f,%f\n", point0._v[0], point0._v[1], point0._v[2]);
        //printf("point1: %f,%f,%f\n", point1._v[0], point1._v[1], point1._v[2]);

        viewer->run();
        return 0;
}

该用户从未签到

发表于 2017-10-30 09:27:11 | 显示全部楼层
上面那个是我写的一个例子,你可以看看

该用户从未签到

发表于 2017-10-30 09:33:45 | 显示全部楼层
这个例子可以很好的对MVPW矩阵的了解,你先按1,2,3,然后一直按0,可以看到效果

该用户从未签到

 楼主| 发表于 2017-12-4 19:32:35 | 显示全部楼层
SunburstRun 发表于 2017-10-30 09:33
这个例子可以很好的对MVPW矩阵的了解,你先按1,2,3,然后一直按0,可以看到效果

好的,太感谢您了,这个问题我解决了,谢谢您给我写的例子,我再好好学习研究一下
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表