查看: 3074|回复: 29

请教前辈高手:如何在osg中绘制一个扇形波束,并控制其绕圆心旋转扫描!!求指导!...

[复制链接]

该用户从未签到

发表于 2014-5-13 12:26:24 | 显示全部楼层 |阅读模式
请教前辈高手:如何在osg中绘制一个扇形波束,并控制其绕圆心旋转扫描!!求指导!...
请教前辈高手:如何在osg中绘制一个扇形波束,并控制其绕圆心旋转扫描!!求指导!...

该用户从未签到

发表于 2014-5-13 16:05:08 | 显示全部楼层
应该是锥形波束、扇形雷达吧?

该用户从未签到

 楼主| 发表于 2014-5-13 20:29:07 | 显示全部楼层
csutest 发表于 2014-5-13 16:05
应该是锥形波束、扇形雷达吧?

用Geometry 绘制了一个三角扇面,关键不知道怎样使他动态的旋转

该用户从未签到

发表于 2014-5-13 20:39:36 | 显示全部楼层
MatrixTransform

该用户从未签到

发表于 2014-5-13 20:40:25 | 显示全部楼层
hrmlove 发表于 2014-5-13 20:29
用Geometry 绘制了一个三角扇面,关键不知道怎样使他动态的旋转

把这个Geomtry添加到node节点,node添加添加到一个MatrixTransform,然后旋转这个MatrixTransform就可以了。

该用户从未签到

 楼主| 发表于 2014-5-13 21:00:00 | 显示全部楼层

这个是旋转后的效果吧,能做出类似动画一样的旋转效果么?

该用户从未签到

发表于 2014-5-13 21:42:24 | 显示全部楼层
MatrixTransform 提供位姿变化的方法。
形状节点以它为父节点,就可以变换姿态了。

做动画可以自己写更新回调
或者使用osg/AnimationPath

该用户从未签到

发表于 2014-5-15 08:25:13 | 显示全部楼层
用geomtry绘制几何体图元,然后绑定到叶节点geode中。最后与MatrixTransform中的makerotate关联

该用户从未签到

 楼主| 发表于 2014-5-15 10:16:23 | 显示全部楼层
鹰灵 发表于 2014-5-15 08:25
用geomtry绘制几何体图元,然后绑定到叶节点geode中。最后与MatrixTransform中的makerotate关联

请问有没有具体详细的实例代码,??
   我绘制好图元geom
        osg::ref_ptr<osg::Geode> geode = new osg::Geode;
        geode->addDrawable(geom.get()); 再将geode加入到root根节点显示。这样可以正常显示
但是 执行
     osg::ref_ptr<osg::MatrixTransform> trans=new osg::MatrixTransform();
    trans->setMatrix(osg::Matrix::rotate(osg:egreesToRadians(90.0),0,1,0));
    trans->addChild(geode.get());
   root->addChild(trans.get());  ----为什么这样没显示

该用户从未签到

 楼主| 发表于 2014-5-15 10:19:32 | 显示全部楼层
cenfer 发表于 2014-5-13 21:42
MatrixTransform 提供位姿变化的方法。
形状节点以它为父节点,就可以变换姿态了。

求相关实例代码??谢谢

该用户从未签到

 楼主| 发表于 2014-5-15 10:27:23 | 显示全部楼层
csutest 发表于 2014-5-13 20:40
把这个Geomtry添加到node节点,node添加添加到一个MatrixTransform,然后旋转这个MatrixTransform就可以 ...

有个问题不懂?

绘制好geom
osg::ref_ptr<osg::Geode>  geode = new osg::Geode;
geode->addDrawable(geom.get());
这时候将geode加入到根节点,即执行root->addChild(geode.get());可以在osg中看到效果(位置固定)
若是执行
osg::ref_ptr<osg::MatrixTransform> trans=new osg::MatrixTransform;
    trans->setMatrix(osg::Matrix::rotate(osg:egreesToRadians(90.0),0,1,0));
    trans->addChild(geode.get());
   root->addChild(trans.get());  这时候无任何效果

该用户从未签到

发表于 2014-5-15 10:33:40 | 显示全部楼层
hrmlove 发表于 2014-5-15 10:27
有个问题不懂?

绘制好geom

你下面的geode节点没加Drawable吧

该用户从未签到

 楼主| 发表于 2014-5-15 10:46:51 | 显示全部楼层
sy2178668 发表于 2014-5-15 10:33
你下面的geode节点没加Drawable吧

第二行代码就是:
geode->addDrawable(geom.get());
难道不是这样??

该用户从未签到

发表于 2014-5-15 10:51:03 | 显示全部楼层
hrmlove 发表于 2014-5-15 10:19
求相关实例代码??谢谢

自己在 osg example 里找吧

该用户从未签到

发表于 2014-5-15 11:01:06 | 显示全部楼层
hrmlove 发表于 2014-5-15 10:27
有个问题不懂?

绘制好geom

注掉这行代码
//trans->setMatrix(osg::Matrix::rotate(osg:egreesToRadians(90.0),0,1,0));

如果看见,说明加旋转后节点不在视野。
不然真的见鬼了!

该用户从未签到

 楼主| 发表于 2014-5-16 15:46:03 | 显示全部楼层
cenfer 发表于 2014-5-15 11:01
注掉这行代码
//trans->setMatrix(osg::Matrix::rotate(osg:egreesToRadians(90.0),0,1,0));

谢谢,是这个问题,旋转后不再视野范围内;有个问题再次麻烦,若是在地表平面绘制好的geom,需要在地平面上做360度的旋转,rotate的参数如何设置;trans->setMatrix(osg::Matrix::rotate(osg:egreesToRadians(90.0),0,1,0));最关键是红色标记的部分,该如何设置,而且他们是什么坐标系下的啊?

该用户从未签到

 楼主| 发表于 2014-5-16 15:53:18 | 显示全部楼层
hrmlove 发表于 2014-5-16 15:46
谢谢,是这个问题,旋转后不再视野范围内;有个问题再次麻烦,若是在地表平面绘制好的geom,需要在地平面 ...

在地表绘制geom图元,需要将世界坐标系(经纬度坐标)转为地心坐标系后加入顶点;然后才在地表位置(我需要的位置)显示;这样的图元,在做水平面360°旋转;将其加入到MatrixTransfrom该如何设置??? 谢谢

该用户从未签到

发表于 2014-5-16 21:29:08 | 显示全部楼层
本帖最后由 cenfer 于 2014-5-22 17:09 编辑
hrmlove 发表于 2014-5-16 15:53
在地表绘制geom图元,需要将世界坐标系(经纬度坐标)转为地心坐标系后加入顶点;然后才在地表位置(我需 ...


1. 求地表的位置和法向量
EllipsoidModel::convertLatLongHeightToXYZ(double latitude, double longitude, double height,
                                              double& X, double& Y, double& Z) ;
osg::Vec3 pos(X,Y,Z);
osg::Vec3 lanNor = pos;lanNor.normalize();

2. 假定你的形状节点shape在自身的局部坐标系位姿是这样的:位置在原点,竖直方向和Z轴同向。
把形状放到目标位置
osg::MatrixTransform* trans;
trans->addChild(shape);
trans->setMatrix(osg::Matrix::rotate(osg::Z_AXIS,lanNor)*osg::Matrix::translate(pos));

水平旋转
float angle;//旋转角度
trans->setMatrix( osg::Matrix::rotate( angle, osg::Z_AXIS*osg::Matrix(trans->getMatirx()->getRotate()) )*
                            osg::Matrix::translate( trans->getMatirx()->getTrans() ) );

注意
前提是没有级联 MatrixTransform 或者 getMatirx()就地心坐标系下的位姿。

该用户从未签到

 楼主| 发表于 2014-5-19 11:48:12 | 显示全部楼层
cenfer 发表于 2014-5-16 21:29
1. 求地表的位置和法向量
EllipsoidModel::convertLatLongHeightToXYZ(double latitude, double longitu ...


2. 假定你的形状节点shape在自身的局部坐标系位姿是这样的:位置在原点,竖直方向和Z轴同向  ??这个不明白,我怎样知道自身的位资,若不是你说的这种又该如何设置???

该用户从未签到

发表于 2014-5-19 13:12:16 | 显示全部楼层
就是你要绘制的形状在局部坐标系中初始位姿啊
比如绘制一个圆柱体。你可以定义圆柱体底面原心在局部坐标系原点,回转轴为局部坐标系Z轴。
然后你就可以把这个初始位姿的圆柱体,旋转平移到世界坐标系的任意方位。

该用户从未签到

 楼主| 发表于 2014-5-19 17:32:37 | 显示全部楼层
cenfer 发表于 2014-5-19 13:12
就是你要绘制的形状在局部坐标系中初始位姿啊
比如绘制一个圆柱体。你可以定义圆柱体底面原心在局部坐标系 ...

谢谢,各种试验后木有成功!!求教啊详细代码啊
XXX类的成员变量
//map容器用于保存创建好的三角扇区
Std::map<int, osg::ref_ptr<osg::Node> > pies;
Osg::ref _ptr <osg::Group> _root ;
Osg::ref_ptr<osg::Group> pieGroup ;
OSG::Vec3d SCANER_POSITION[] ={
osg::Vec3d (Lng1, Lat1,Heig),
osg::Vec3d (Lng2, Lat2,Heig),
osg::Vec3d (Lng3, Lat3,Heig),
osg::Vec3d (Lng4, Lat4,Heig),
osg::Vec3d (Lng5, Lat5,Heig),
osg::Vec3d (Lng6, Lat6,Heig)
}

//构造中
有执行:
   _root = new osg::Group()
   viewerWidget = new osg::Earth:tGui::ViewerWidget(_root);
   viewerWidget->getView(_views);

   pieGroup = new osg::Group();
   _root->addChile(pieGroup.get());

//创建三角波束
Void XXX::createPie()
{
for(int i = 0; i < 6; i++)
{       
        //扇区的3个顶点
        double x1 =0, y1 =0, z1=0;
        double x2=0, y2=0, z2=0;
        double x3=0, y3=0, z3=0;

//将大地坐标转为地心坐标
VrUtil::CoordinateCentralEarthLonLatH2xyz(
        SCANER_POSITION.x() + 0.0013* sin(30*M_PI/180),
        SCANER_POSITION.y () + 0.0013* cos(30*M_PI/180),
        SCANER_POSITION.z (),
x1, y1, z1);
VrUtil::CoordinateCentralEarthLonLatH2xyz(
        SCANER_POSITION.x()
        SCANER_POSITION.y ()
        SCANER_POSITION.z (),
X2, y2, z2);

VrUtil::CoordinateCentralEarthLonLatH2xyz(
        SCANER_POSITION.x() + 0.0013* sin(45*M_PI/180),
        SCANER_POSITION.y () + 0.0013* cos(45*M_PI/180),
        SCANER_POSITION.z (),
X3, y3, z3);
osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;
osg::ref_ptr<osg::Vec3Array> vPoint = new osg::Vec3Array;
geom->setVertexArray(vPoint.get());
vPoint ->push_back(osg::Vec3d(x1, y1, z1));
vPoint ->push_back(osg::Vec3d(x2, y2, z2));
vPoint ->push_back(osg::Vec3d(x3, y3, z3));

osg::ref_ptr<osg::Vec4Array> vColor = new osg::Vec4Array;
geom->setColorArray(vColor.get());
geom.->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
vColor->push_back(osg::Vec4(1.0f, 0.1f,0.3f,0,3f));
vColor->push_back(osg::Vec4(1.0f, 0.1f,0.3f,0,3f));
vColor->push_back(osg::Vec4(1.0f, 0.1f,0.3f,0,3f));
geom->addPrimitiveSet(new osg:rawArrays(osg:rimitivSet::TRIANGLE_FAN,0,3));
//设置透明度
osg::ref_ptr<osg::StateSet> stateSet = new osg::StateSet;
stateSet->setModel(GL_BLEND, osg::StateAttribute::OFF);
stateSet->setModel(GL_DEPTH_TEST, osg::StateAttribute::OFF);
stateSet->setModel(GL_LIGHTING, osg::StateAttribute::PROTECTED);
stateSet->setRenderingHintl( osg::StateSet::Attribute::TRANSPARENT_BIN);

osg::ref_ptr<osg::Geode> geodPie = new osg::Geode;
geodePie->addDrawable(geom..get());

pies.insert(std::map<int, osg::ref_ptr<osg::Node> >::value_type(i+1, geodePie));
}



//旋转:
Void XXX::movePies()
{
Std::map<int , osg::ref_ptr<osg::Node>  >::ieerator itNode = pies.begin();
While(itNode != pies.end())
{
        Osg::ref_ptr<osg::MatrixTransform> trans = new  osg::MatrixTransfrom();
  trans ->addChild(itNode->second.get());
  pieGroup ->addChild(trans.get())

  //如何设置旋转???
   代码????


itNode++;
}


}

该用户从未签到

发表于 2014-5-19 18:51:41 | 显示全部楼层
本帖最后由 cenfer 于 2014-5-19 18:59 编辑

简单看了下代码。你是直接计算了每个顶点在地心坐标系下的坐标;
这样就没有必要用osg::MatrixTransform了。

按你的实现方法,旋转需要重新计算每个顶点的坐标,重新绘制。

该用户从未签到

 楼主| 发表于 2014-5-19 20:37:19 | 显示全部楼层
cenfer 发表于 2014-5-19 18:51
简单看了下代码。你是直接计算了每个顶点在地心坐标系下的坐标;
这样就没有必要用osg::MatrixTransform了 ...

那这样的方法就不便于操作其旋转啊,求教该如何绘制??

该用户从未签到

发表于 2014-5-19 20:58:48 | 显示全部楼层
如何绘制在18楼已经告诉你了
如果不明白,我没有更好了的建议了!

该用户从未签到

 楼主| 发表于 2014-5-19 21:55:25 | 显示全部楼层
cenfer 发表于 2014-5-19 20:58
如何绘制在18楼已经告诉你了
如果不明白,我没有更好了的建议了!

OK!! 非常感谢!!!!明天白天在多试验下!!

该用户从未签到

发表于 2014-5-19 22:39:51 | 显示全部楼层
osgSim::Shpere 节点,osgSim库中有一个现成的节点。
记得osgExample里有一个类似的例子的,你可以参考下。

该用户从未签到

 楼主| 发表于 2014-5-21 11:51:19 | 显示全部楼层
cenfer 发表于 2014-5-19 18:51
简单看了下代码。你是直接计算了每个顶点在地心坐标系下的坐标;
这样就没有必要用osg::MatrixTransform了 ...

绘制图元是push_back的顶点坐标是在属于什么坐标系啊,我若不计算成地心坐标,绘制后不知道他去哪了啊??求教!

该用户从未签到

发表于 2014-5-22 11:08:14 | 显示全部楼层
希望你能 把形状和位姿剥离开来

该用户从未签到

发表于 2014-5-22 11:19:51 | 显示全部楼层
本帖最后由 cenfer 于 2014-5-22 11:23 编辑

举个例子吧,
比如你在地球上栽棵树,你需要知道树上每个顶点的地心坐标?!显然不是!
总是在一个局部坐标系下以简单的位姿把模型制作或者绘制出来,用一些特征点和特征方向代表这个模型。
然后根据特征点和特征方向把模型旋转平移到目标位姿。

该用户从未签到

 楼主| 发表于 2014-5-22 20:18:02 | 显示全部楼层
cenfer 发表于 2014-5-22 11:19
举个例子吧,
比如你在地球上栽棵树,你需要知道树上每个顶点的地心坐标?!显然不是!
总是在一个局部坐 ...

嗯,懂你的意思:
   思路: 绘制图元--->矩阵变换---->回调更新
    就是在局部的坐标系中绘制好基本图元,就那我上面的说:绘制好三角扇面;
    然后再经过矩阵变换到目标位置(地球上需要的实际位置);
    再在这一上做旋转变换(360度地表旋转),回调 ;
   这样就实现了360度的水平周扫波束!!
   
   现在我的问题在于:参考了许多例子关于绘制图元的,push_back顶点,如顶点1.Vec3(3,2,0),顶点2.Vec3(0,0,0),顶点3.Vec3(2,3,0),
    这顶点联结绑定方式为三角扇面,是可以的吧?由于扇面位于三维坐标中的xy平面,设置其法线为Z轴方向,即Vec3(0,0,1);这样应该也没有问题吧?但是在接下来的位置变换矩阵该如何设置OSG:uat四元数,修改了无数次,还是不知道吧图元弄到哪去了?不在视野上!求指导!!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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