当前位置: 首页 > news >正文

大良做网站哈尔滨网站推广

大良做网站,哈尔滨网站推广,全国建筑行业资质平台查询,怎么判断网站被k这里写目录标题功能原理视点投影鼠标滚轮旋转平移全部代码:功能 本节模拟一个AutoCAD的操作器,发现有很多网友是在使用OSG做CAD相关的操作,问题了很多关于使用正交操作器的问题。本文功能如下: 绘制一个线框当背景正交投影鼠标滚…

这里写目录标题

  • 功能
  • 原理
    • 视点
    • 投影
    • 鼠标滚轮
    • 旋转
    • 平移
      • 全部代码:

功能

本节模拟一个AutoCAD的操作器,发现有很多网友是在使用OSG做CAD相关的操作,问题了很多关于使用正交操作器的问题。本文功能如下:

  • 绘制一个线框当背景
  • 正交投影
  • 鼠标滚轮向上向下,可以放大缩小线框
  • 点击a/d键向视点向左/右移动
  • 点击q键逆时针旋转线框

本节的内容在网盘中:

【击此打开网盘资源链接】

原理

视点

首先我们要明白,视点位置与投影是两码事。视点的位置由三个要素决定,_eye(眼睛的位置),_center(你在往哪个点看),_up(你头顶指向哪里,可以想象你歪脖子就是改变了up)

而投影就不同了,投影是你怎么看这个世界,人的眼睛是近大远小的透视投影,我们就不说了。本文要使用的投影要做正交2D投影,就是眼睛位置确定之后,只取眼睛左-右,下-上,这么大的范围的数据,且没有近大远小,这个范围内的全部叠加在一起。

想象一个从视点出发无限长的方形的管道,管道里的所有物体叠于一个面上,那就是正交投影显示的结果。当然正交投影也可以设置远-近,就是不是无限长的方形管道。此处不做过多说明。不设置默认是无限长的。

本文操作器我们仍然做了如下定义:

		_center = osg::Vec3(0.0, 0.0, 0.0);_up = osg::Vec3(0.0, 0.0, 1.0);_eye = osg::Vec3(0.0, -10.0, 0.0);

也就是默认的情况下我们站在y轴的-10的位置,看向原点。在这里我们要有空间的概念,x轴向屏幕右,y轴向屏幕里,z轴向屏幕上。

可以认为当前我们站在离屏幕10的距离朝向屏幕看,且头顶朝向屏幕的上方。如下图所示,x是屏幕右,z是屏幕上,狮子所在的位置是 负y轴的方向,也就是y轴朝向屏幕里。
在这里插入图片描述

投影

对于正交投影来说,参数特别的简单,就是left, right, bottom, top,这个是相对于视点来说的,想象视点在管道中间(0, 0)点, left就是管道左壁,right就是右壁,bottom就是下壁,top就是上壁。

因为我们绘制的网格是在xz平面上,1米划一条线,总共划20条,从(0, 0)开始划到(19, 19),视点又在(0, 0)点,因此我们把left, right, top, bottom这么设置:

		_l = -2.0;_r = 2.0;_b = -2.0;_t = 2.0;

会只看到两个网格:
在这里插入图片描述

鼠标滚轮

滚轮事件的处理是最简单的,我们只需要重新定义left, right, top, bottom的范围即可。让其更大或者更小。

旋转

旋转其实就是改变up的方向,我们定义了_theta,每点一次q我们就把其加1。然后将初始up = osg::Vec3(0.0, 0.0, 1.0) 绕y轴旋转_theta即可。

平移

本例只处理了a左移与d右移,当不旋转的时候,视点左移_deltaEye=0.3这么远。当鼠标滚轮时,因为视场变大了_deltaEye也会跟着left, right一起变大变小。这个不难理解。

假如我们不旋转,我们只点a向左平移是这样的:
在这里插入图片描述
我们只需要将eye的位置,沿x方向减去deltaEye就可以了。这就是我注释的代码:
//_eye += osg::Vec3(-_deltaEye, 0.0, 0.0);

那么现在旋转了,情况复杂了,当我们点击q的时候,旋转_theta度,假设在0~90度内,情况变这样了:
在这里插入图片描述
上图粗线是要行走的_deltaEye,旋转角度_theta后,红线画的是其在x方向上与y方向上的变化,在0~90度内,sin与cos都是正的,因此新eye的位置为:

_eye += osg::Vec3(-_deltaEye*std::cos(osg::inDegrees(_theta)), 0.0, _deltaEye*std::sin(osg::inDegrees(_theta)));

eye一改,center也要改

_center = osg::Vec3(_eye.x(), 0.0, _eye.z());

也就是永远站在屏幕外,看屏幕里,你怎么移都是这样。因为y值没有变化,eye的y永远是-10,永远看向y=0

其它的情况读者自己推吧,旋转[90, 360]的时候公式还一样吗?以及w向上s向下用户都可以自己写。或者鼠标拖动等,用户都可以自己写。

全部代码:

#include <osgViewer/Viewer>
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/PrimitiveSet>
#include <osgGA/CameraManipulator>class MyCameraManipulator : public osgGA::CameraManipulator
{
public:MyCameraManipulator(){_theta = 0.0;_center = osg::Vec3(0.0, 0.0, 0.0);_up = osg::Vec3(0.0, 0.0, 1.0);_eye = osg::Vec3(0.0, -10.0, 0.0);_deltaEye = 0.3;_l = -2.0;_r = 2.0;_b = -2.0;_t = 2.0;}//这三个纯虚函数本例不会使用virtual void setByMatrix(const osg::Matrixd& matrix) {};virtual void setByInverseMatrix(const osg::Matrixd& matrix) {};virtual osg::Matrixd getMatrix() const { return osg::Matrix::identity(); };//最关键的是这个,这个返回的就是ViewMatrixvirtual osg::Matrixd getInverseMatrix() const{return osg::Matrix::lookAt(_eye, _center, _up);};//事件处理,我们要点击A就围着Z轴顺时针转动,点D就逆时针转动,转的时候始终朝0 0 0 点看着virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us){if (ea.getEventType() == osgGA::GUIEventAdapter::FRAME){us.asView()->getCamera()->setProjectionMatrixAsOrtho2D(_l, _r, _b, _t);}if (ea.getEventType() == osgGA::GUIEventAdapter::SCROLL){//判断滚动的方向osgGA::GUIEventAdapter::ScrollingMotion sm = ea.getScrollingMotion();if (sm == osgGA::GUIEventAdapter::SCROLL_DOWN){_deltaEye *= 1.1;_l *= 1.1;_t *= 1.1;_b *= 1.1;_r *= 1.1;}else{//范围变小0.1,正好与变大相反,左右同时往里缩_deltaEye *= 0.9;_l *= 0.9;_t *= 0.9;_b *= 0.9;_r *= 0.9;}}if (ea.getEventType() == osgGA::GUIEventAdapter::KEYDOWN){//旋转视角if ((ea.getKey() == 'Q') || (ea.getKey() == 'q')){//点q变1度_theta += 1;_up = osg::Vec3(0.0, 0.0, 1.0)*osg::Matrix::rotate(osg::inDegrees(_theta), osg::Y_AXIS);}//若是A键if ((ea.getKey() == 'A') || (ea.getKey() == 'a')){//_eye += osg::Vec3(-_deltaEye, 0.0, 0.0);_eye += osg::Vec3(-_deltaEye*std::cos(osg::inDegrees(_theta)), 0.0, _deltaEye*std::sin(osg::inDegrees(_theta)));_center = osg::Vec3(_eye.x(), 0.0, _eye.z());}if ((ea.getKey() == 'D') || (ea.getKey() == 'd')){//_eye += osg::Vec3(_deltaEye, 0.0, 0.0);_eye -= osg::Vec3(-_deltaEye*std::cos(osg::inDegrees(_theta)), 0.0, _deltaEye*std::sin(osg::inDegrees(_theta)));_center = osg::Vec3(_eye.x(), 0.0, _eye.z());}}return false;}//视点位置osg::Vec3d              _eye;//点击鼠标a键向左移的量度,随着鼠标滚轮的放大缩小,这个量度也在变化double _deltaEye; //视点看向哪里osg::Vec3d              _center;//头顶的朝向osg::Vec3d              _up;//视点看向0 0 0的角度float              _theta;//二维投影参数, left, right, bottom, topdouble _l, _r, _b, _t;
};osg::Geode* createNet()
{osg::Geode* gnode = new osg::Geode;osg::Geometry* geom = new osg::Geometry;gnode->addDrawable(geom);//设置线的颜色为白色osg::Vec4Array* color = new osg::Vec4Array;color->push_back(osg::Vec4(1.0, 1.0, 1.0, 1.0));geom->setColorArray(color, osg::Array::BIND_OVERALL);osg::Vec3Array* vertex = new osg::Vec3Array;geom->setVertexArray(vertex);//间隔1米,横20条,竖20条for (int i = 0; i < 20; i++){//x方向vertex->push_back(osg::Vec3(0, 0, i));vertex->push_back(osg::Vec3(17, 0, i)); //设置为17,不画满//z方向vertex->push_back(osg::Vec3(i, 0, 0));vertex->push_back(osg::Vec3(i, 0, 17));}geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES, 0, vertex->size()));geom->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);return gnode;
}int main()
{osgViewer::Viewer viewer;viewer.setSceneData(createNet());viewer.setCameraManipulator(new MyCameraManipulator());return viewer.run();
}
http://www.lbrq.cn/news/2779219.html

相关文章:

  • 石家庄网站建设就找企行家网络宣传平台有哪些
  • 杭州网站模板建站免费发布友链
  • 网站的会员系统怎么做seo销售
  • 山东济南网站建设公司计算机基础培训机构
  • 西安做网站推广宣传推广网络推广
  • 微信编辑器做网站百度搜索竞价推广
  • 临朐网站建设定制首选哪家公司成都网络营销推广
  • 太原网站制作建设怎么自己建网站
  • 印江建设局网站百度搜索引擎盘搜搜
  • 大学生做兼职的网站有哪些站长网站大全
  • 手机网站营销的网站西安网站公司推广
  • 广东省建设信息网站企业网站建设公司
  • 专业建设网站哪家好百度快照是什么
  • 网站方案案例怎么做seo综合查询平台官网
  • 招工网站58同城朔州seo
  • 做网站什么科目宁波最好的seo外包
  • 好的网站建设天津seo管理平台
  • 手机app网站模板下载windows优化大师和鲁大师
  • 怎样能注册自己的网站网页制作工具有哪些
  • 北京网站建设怎么样天怎样创建一个网站
  • 二级域名指向 独立网站做网站推广一般多少钱
  • 如何建做校园购物网站肇庆网站建设制作
  • 做网站需要阿里云吗太原百度seo排名软件
  • 结合七牛云做视频网站福州关键词排名优化
  • 哪个网站专做民宿软件开发
  • 做网站的一些话术chatgpt 链接
  • 建设部电教中心网站seo自学网免费
  • wordpress内置播放器百度搜索seo
  • 中国进出口贸易官网网站建设优化哪家公司好
  • 营销网站建站公司转让如何进行app推广
  • OceanBase DBA实战营2期--SQL 关键字限流学习笔记
  • 【PostgreSQL内核学习:WindowAgg 节点对 Tuplestore 的复用机制】
  • 在 React 中,​父子组件之间的通信(传参和传方法)
  • idea中如何设置文件的编码格式
  • 数字ic后端设计从入门到精通14(含fusion compiler, tcl教学)半定制后端设计
  • 驱动开发系列66 - glCompileShader实现 - GLSL中添加内置函数