精华内容
下载资源
问答
  • OpenGL视口变换

    2015-05-20 13:51:20
    OpenGL利用C语言做出4个不同的视口,每个视口中都有一个按不同方向旋转的带颜色的四棱锥,C语言代码完整,并标注完整注释,适合初学者参考学习。
  • 目录 关于矩阵的计算可以看另一篇博客 关于透视矩阵如何实现可以看另一篇博客 观察视图 视图变换 模型变换 投影变换(视锥体设置) 应用变换结果 视口变换 (设置剪切坐标到窗口坐标的映射方式)glClipControl(GLenum ...

    关于矩阵的计算可以看另一篇博客

    计算机图形学第二天

    关于透视矩阵如何实现可以看另一篇博客

    OpenGL3.3透视矩阵原理计算

    观察视图

    视图变换

    将设置好的摄像机放置到世界中

    模型变换

    将准备拍摄的对象移动到场景中必要的位置上

    投影变换(视锥体设置)

    设置相机的焦距 或者调整缩放比例 只是对捕捉场景的范围大小 不对结果进行拉伸

    应用变换结果

    拍摄照片

    视口变换

    对结果图像进行拉伸或者挤压 将它变换到需要 的图片大小
    将裁剪空间的坐标转换到屏幕坐标空间的过程叫做视口变换 视口变换将位于-1.0到1.0范围的坐标变换到由glViewport函数所定义的坐标范围内
    剪切空间坐标(0,0)一般会被映射到窗口空间的中心
    x坐标轴正向指向右侧
    y坐标轴正向指向上方
    (-1,-1)位于窗口的左下方
    (1,1)位于窗口右上方

    (设置剪切坐标到窗口坐标的映射方式)glClipControl(GLenum origin,GLenum depth)

    origin设置的是窗口坐标x和y的原点
    origin必须是GL_LOWER_LEF或者GL_UPPER_LEFT中的一个
    GL_LOWER_LEF:剪切空间x,y坐标(-1,-1)对应窗口左上角 y轴正向对应窗口空间的下方向
    depth设置的是剪切空间深度值映射到glDepthRange()所设置的数值的方式
    depth可以为:
    GL_NEGATIVE_ONE_TO_ONE:窗口空间深度值对应于剪切空间的[-1,1]
    GL_ZERO_TO_NOE:剪切空间[0,1]被映射到窗口空间深度值 0.0表示近平面 1.0表示远平面 剪切空间的z负值将被处于近屏幕后方 但是观察者眼前的数据进度之会被的更高

    在这里插入图片描述

    坐标变换顺序

    模型局部坐标系->世界坐标系->观察空间坐标(眼坐标系)->裁剪坐标系(投影变换)->屏幕坐标系
    **局部空间 **:物体自己的坐标 每个物体有自己的坐标 原点 所以局部空间有很多个 键盘输入的坐标就是局部坐标空间
    **世界空间 **:就是所有物体都在的一个空间 局部空间坐标*世界空间的位置=该物体在世界空间的每个顶点的坐标 就是局部坐标×model就是进入世界空间
    **观察空间 **:大概的理解就是摄像机的视角里的空间,每个坐标都是从摄像机或者说观察者的角度进行观察的 世界坐标×view就是进入观察空间
    **齐次裁剪空间(cvv) **:这个空间并不是视锥体空间 而是(1,-1)(1,-1)(1,-1)标准化空间 由投影矩阵创建的观察箱被称为平截头体,将特定范围内的坐标转化到标准化设备坐标系(应该就是齐次裁剪空间)的过程(而且它很容易被映射到2D观察空间坐标)被称之为投影 观察空间×projection就是进入cvv空间
    NDC空间:这个空间是在cvv空间裁剪之后进行透视除法(/w)之后就进去NDC空间 这个空间的坐标是最容易转化到屏幕空间
    屏幕空间:将裁剪空间的坐标转换到屏幕坐标空间的过程叫做视口变换 视口变换将位于-1.0到1.0范围的坐标变换到由glViewport函数所定义的坐标范围内 最后变换出来的坐标将会送到光栅器,将其转化为片段

    齐次坐标

    为什么需要齐次坐标:
    1.实现对三维坐标的平移(易于仿射变换)(因为线性变换有个重要规则 :(0.0,0.0,0.0)坐标和三维坐标或者三维矩阵进行乘除一定是(0.0,0.0,0.0) 所以如果不添加一齐次坐标 三维坐标就一定不能实现平移)
    2.实现透视效果

    线性变换

    f(x)=Ax
    线性变换从几何直观有三个要点:
    1.变换前是直线的,变换后依然是直线
    2.直线比例保持不变
    3.变换前是原点的,变换后依然是原点

    仿射变换:

    f(x)=Ax+b
    也就是相对于线性变换 新增了平移变换
    实际上就是增加一个维度 通过高维度的线性变换完成低纬度的仿射变换
    在这里插入图片描述
    特点:
    (1)凸性
    (2)共线性:若几个点变换前在一条线上,则仿射变换后仍然在一条线上
    (3)平行性:若两条线变换前平行,则变换后仍然平行
    (4)共线比例不变性:变换前一条线上两条线段的比例,在变换后比例仍然共线 比例相同

    如何通过高纬度线性变换完成低纬度的仿射变换

    如下图 将二维的图形放到三维的z=1平面上 z=1和z=0的图形就形成了一个柱子 然后再让柱体做推移变换(线性变换之一) 最后将图形还原到二维就形成了平移的效果
    在这里插入图片描述

    如何通过齐次坐标实现透视效果

    如果齐次坐标最后一个分量为0 则表示这个点在无穷远的地方 在平行线最终相交的位置就是无穷远的地方
    透视变换会把齐次坐标的w值修改为1.0以外的值
    如果齐次坐标中w的值越大 那么坐标就离摄像机越远 因为OpenGL在准备绘制几何体的时候 他会使用w分量除以前面的三个分量 将齐次坐标变回笛卡尔坐标
    裁剪(视锥剔除)和NDC转换都已集成到GL_PROJECTION
    NDC是Normal Device Coordinate的简写(标准设备(屏幕)坐标系)
    物体的坐标从世界坐标系剪切到视景体的坐标中(由近平面和远平面形成的一个视景体)(具体就是投影到近平面上)在这里插入图片描述
    注意:视景体坐标系和标准设备坐标系是不同方向的坐标系

    透视投影

    有两种情况的透视投影:
    1.中心对称的视图截锥 z轴位于锥体的中央位置
    2.不对称的视图截锥 就像靠近窗口又没有正对窗口的情况
    对于这两种情况 在这个坐标系内 观察点(摄像机的位置)都是位于(0,0,0)并且朝向z轴正方向

    视口

    glViewport(GLint x,GLint y,GLint width,GLint height)

    在窗口中定义一个矩形的像素区域 并且将最终渲染的图像映射到其中
    x,y设置了视口左下角的坐标 width和height设置了视口矩形的像素大小 默认情况为 (0,0,winWidth,winHeight)winWidth和winHeight为窗口的像素尺寸

    用户裁剪和剪切(目前还不知道怎么用)

    看到一篇还不错的博客里面有解释但是也不全
    别人的博客

    gl_CullDistance[](裁剪平面)(裁剪整个图元)

    裁剪平面最大值是gl_MaxCullDistancs
    如果图元的所有顶点对于平面都返回了负数的裁减距离值,那么整个图元需要被裁减。
    在着色器中使用时需要手动声明他的大小 或将他作为一个编译时的常量使用 (也就是gl_CullDistance[2]需要写数字)数字表示我们将要使用的平面数量
    在不同的着色器中声明的gl_CullDiastance[]和gl_ClipDistance[]数字都必须一样

    gl_ClipDistance(剪切平面)(截掉部分图元)

    剪切平面最大值是gl_MaxClioDistances

    输出的裁剪距离将和图元进行线性插值,插值距离小于0,则图元部分将剪切掉(也就是插值距离小于0的那部分被剪切掉
    距离为0表示顶点落在平面之上 正数值表示顶点在剪切平面内测(保留这个顶点) 图元中剪切距离是线性插值OpenGL会将完全落在某个裁剪平面之外的图元剔除(如果图元与所有裁剪平面相交且一部分落在他们的内测 则认为它应当被保留) 而且OpenGL会直接抛弃所有距离值小于0的片元

    启用剪切平面

    glEnable(GL_CLIP_PLANE0) 还有GL_CLIP_PLANE1,GL_CLIP_PLANE2等 这些枚举时按顺序定义的 因此GL_CLIIP_PLANEi总是等价于GL_CLIP_PLANE0+i 着色器必须卸任所有启用的平面距离值 否则会得到奇怪的剪切结果

    gl_ClipDistance和gl_CullDistance[]的关系

    gl_ClipDistance和gl_CullDistance的每个元素都对应于一个平面 平面数量有限 一般是八个 通常这个数量是gl_ClipDistance和gl_CullDistance共享 可以是8个剪切平面 也可以是8个裁剪平面 也可以各4个 但是两个数组的平面总数不能超过8个 可以用gl_MaxCombinedClioAndCullDistances来查询平面总数具体值

    使用例子gl_ClipDistance和gl_CullDistance[]

    先在绘制之前开启glEnable(GL_CLIPDISTANCE0);
    然后再着色器中:
    #version 450 core
    uniform vec4 Plane;//平面方程 Ax+By+Cz+D = 0
    in vec4 Vertex; //w = = 1.0
    float gl_ClipDistance[1];//使用一个剪切平面 如果不写这个应该是默认只有一个GL_CLIPDISTANCE0可以用
    void main()
    {
    /计算平面方程/
    gl_ClioDistance[0] = dot(Vertex,Plane);
    //也可也使用gl_CullDistance[0];//来进行裁剪
    //gl_ClipDistance[0] = Plane[3] - Plane[0]*aPos.x - Plane[1]*aPos.y - Plane[2]*aPos.z;
    //就是在程序中传值给着色器中的Plane 然后通过这个式子计算是否大于0 如果大于0 才会被显示出来
    }

    作用结果

    原来的样子
    在这里插入图片描述

    gl_ClipDistance作用
    在这里插入图片描述
    gl_CullDistance作用
    在这里插入图片描述

    摄像机的原理

    想要实现摄像机的效果 OpenGL本身没有摄像机(Camera)的概念,但我们可以通过把场景中的所有物体往相反方向移动的方式来模拟出摄像机,产生一种我们在移动的感觉,而不是场景在移动。

    展开全文
  • 一、模型视图变换 模型视图变换主要是为了让摄像机回归到世界坐标的原点并且和拍摄物体一起进行变换,便于计算 模型视图变换的根据就是物体和相机的相对位置不变,那么,投影得到的图片也是不变的 首先规定相机...

    一、模型视图变换

    模型视图变换主要是为了让摄像机回归到世界坐标的原点并且和拍摄物体一起进行变换,便于计算

    模型视图变换的根据就是物体和相机的相对位置不变,那么,投影得到的图片也是不变的

    首先规定相机拍摄方向朝向-Z,相机的位置位于e,相机的正上方可以用向量t来表示,那么将相机移动到世界坐标的原点的过程如下图

    首先需要将相机平移值世界坐标原点,平移矩阵就可以写成

    然后分别需要将g旋转到-Z,将t旋转到Y,将g叉积t的方向旋转到X,然而,这个旋转对应的旋转矩阵并不容易写出,但是如果将Z旋转到-g,将Y旋转到t,将X旋转到g叉积t的方向

    那么,这个逆向的旋转矩阵就可以写成

    之所以可以这样写,是因为旋转矩阵是正交矩阵,其列向量或列向量可以构成一组正交基向量,而t, -g以及g与t的叉积可以构成一组正交基,所以直接将g与t的叉积方向、t方向与-g方向的三个向量填入旋转矩阵,并且这三个向量可以表示旋转后的向量。于是就有了逆向旋转矩阵

    因为旋转矩阵是正交矩阵,所以逆矩阵也是矩阵的转置,所以,此时只需将逆矩阵再次进行转置,就可以得到原来的旋转矩阵

    所以,将将g旋转到-Z,将t旋转到Y,将g叉积t的方向旋转到X的旋转矩阵就是逆矩阵的转置

    所以,模型视图变换矩阵最终的结果就是

    二、投影变换

    2.1、正交投影

    正交投影假设先把相机移到无穷远处,此时,无论物体离相机多远,投影出来后,物体的大小都是一样的(深度信息被忽略),没有所谓的近大远小的特点,这就是正交投影

    2.2、正交投影矩阵

    如上图,假设空间中存在一个长方体,最终三个方向均要正交投影到一个标准立方体中,那么首先需要将长方体的中心平移到原点(此时长方体的中心与原点重合,上图画的不太标准),然后该长方体进行一个缩放变换,缩放到标准立方体中,所谓的标准立方体就是在三维坐标中,立方体在XYZ正方向的区域的坐标是(1,1,1),而在XYZ负方向的坐标是(-1,-1,-1),缩放到标准立方体中是为了方便进行后续的视口变换的计算方便。

    立方体的坐标表示如下图

    所以,平移矩阵可以表示为

    平移举例表示中心点要移动的距离,因为是向原点移动,所以需要加负号

    平移变换之后,需要进行缩放变换,缩放因子可以表示为

    所以,缩放矩阵就可以表示为

    所以,最终的正交投影矩阵就是平移矩阵与缩放矩阵的乘积

    2.3、透视投影

    如下图所示,透视投影并包含深度信息,并因为深度信息而产生近大远小的特点,符合人眼的视觉模型

    正交投影中光线的是平行光,而透视投影中的光则是点光源,如下图

    2.4、透视投影矩阵

    因为透视投影是要通过近大远小表达深度的,而透视投影就是将上图中的棱锥无限切分,然后,全部缩放成近平面的大小。最后,将缩放后的长方体再平移缩放到标准立方体中

    所以投影矩阵推导的思路就是:将棱锥模型的四个棱向内挤压内,形成一个长方体,之后将长方体进行一次平移和缩放,使得最终结果处于标准立方体中,也就是说对长方体进行正交投影,最终得到的投影就是透视投影。

    将棱锥远平面上的任意一点投影到屏幕后的模型可以表示为

    根据相似三角形可得

    同理可得

    到此,也就是说棱锥内的所有的点的xy坐标都经过了缩放因子为n/z的挤压

    所以,变换的形式可以写为

    齐次坐标的同乘一个数或者同除以一个不为零的数时,齐次坐标不发生变化,所以,将等号右侧同时乘以z,那么形式就写成

    此时,矩阵M可以写成

    如何算出pqab这四个值?

    首先,棱锥近平面压缩后,近平面上的所有点依然不变,且近平面上的点的z坐标都是n,所以可以得出如下方程

    此时,再次利用齐次坐标的不变性,将右边的向量同乘以n,可得

    可知,等式右边的结果与xy无关,所以,p=0,q=0

    所以,上式最终变为

    此外,远平面处的中心点(0,0,f,1)经过挤压后,也没有变化。所以,可以的导入下的方程

    联立上述两个方程

    最终可得

    所以,该转换矩阵可以写为

    所以,最终的透视投影矩阵就是该转换矩阵和正交投影矩阵的乘积

    三、视口变换

    经过了MVP变换,可以将任意三维空间中的物体投影到标准立方体上,但是之后还需要投影到二维平面上进行显示(Z方向暂时不考虑)

    所以,就需要将标准立方体中的中的点,转换到屏幕上,所以还是需要先平移,再缩放,形式同正交矩阵

    平移分量的符号是正的,是因为中心点远离原点;width/2是缩放因子(从[-1, 1]*[-1, 1]->[0, width]*[0, height])

    四、其他概念

    4.1、相机的视场(FOV,field of view)

    相机的视场分为水平方向和垂直方向,上图表示的是水平方向的视场,视场决定相机的视野的大小

    FOV的大小与焦距有关

     FOV的大小也与成像平面有关

     因为屏幕的尺寸是一定的,所以,如果FOV越大,那么,包含进来的物体就越多,那么,成像后,物体在屏幕中就显得比较小比较拥挤,反之,如果FOV越小,包含的物体就越少,那么,成像后,物体在屏幕中就显得比较大

     

    4.2、屏幕的宽高比(aspect ratio)

     

    屏幕的宽高比决定了图像能否正常显示,如果宽高比过大,那么,出现在屏幕上的画面就会变得矮胖,如果宽高比过小,出现在屏幕上的画面就会变得高瘦,所以,合适的宽高比将会使得图像更好的现实在屏幕上

    参考:

    GAMES101-现代计算机图形学入门-闫令琪_哔哩哔哩_bilibili

    欢迎大家评论交流,作者水平有限,如有错误,欢迎指出

    展开全文
  • opengl中模型变换,投影变换,视点变换,视口变换比较让人头晕,看个这个演示就会有清楚的认识啦 http://www.99pan.com/Invite?uid=171324
  • OpenGL学习脚印: 投影矩阵和视口变换矩阵(math-projection and viewport matrix) ...

    OpenGL学习脚印: 投影矩阵和视口变换矩阵(math-projection and viewport matrix)

    写在前面
    前面几节分别介绍了模型变换视变换,本节继续学习OpenGL坐标变换过程中的投影变换。这里主要是从数学角度推导投影矩阵。对数学不感兴趣的,可以稍微了解下,或者跳过本节内容。

    本文主要翻译并整理自 songho OpenGL Projection Matrix一文,这里对他的推导思路稍微进行了整理。

    通过本节可以了解到

    • 透视投影矩阵的推导
    • 正交投影矩阵的 推导
    • 视口变换矩阵的推导
    • zFighting问题

    投影变换

    OpenGL最终的渲染设备是2D的,我们需要将3D表示的场景转换为最终的2D形式,前面使用模型变换和视变换将物体坐标转换到照相机坐标系后,需要进行投影变换,将坐标从相机—》裁剪坐标系,经过透视除法后,变换到规范化设备坐标系(NDC),最后进行视口变换后,3D坐标才变换到屏幕上的2D坐标,这个过程如下图所示:

    坐标变换

    投影变换通过指定视见体(viewing frustum)来决定场景中哪些物体将可能会呈现在屏幕上。在视见体中的物体会出现在投影平面上,而在视见体之外的物体不会出现在投影平面上。投影包括很多类型,OpenGL中主要考虑透视投影(perspective projection)和正交投影( orthographic projection)。两者之间存在很大的区别,如下图所示(图片来自Modern OpenGL):

    投影类型

    上面的图中,红色和黄色球在视见体内,因而呈现在投影平面上,而绿色球在视见体外,没有在投影平面上成像。

    指定视见体通过(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble nearVal, GLdouble farVal)6个参数来指定。注意在相机坐标系下,相机指向-z轴,nearVal和farVal表示的剪裁平面分别为:近裁剪平面z=nearValz=−nearVal。推导投影矩阵,就要利用这6个参数。在OpenGL中成像是在近裁剪平面上完成。

    透视投影矩阵的推导

    透视投影中,相机坐标系中点被映射到一个标准立方体中,即规范化设备坐标系中,其中[l,r][1,1][l,r]映射到[−1,1],如下图所示:
    视见体和NDC

    注意到上面的相机坐标系为右手系,而NDC中+z轴向内,为左手系。

    我们的目标

    求出投影矩阵的目标就是要找到一个透视投影矩阵P使得下式成立:

    ⎡⎣⎢⎢⎢xcyczcwc⎤⎦⎥⎥⎥=P⎡⎣⎢⎢⎢xeyezewe⎤⎦⎥⎥⎥[xcyczcwc]=P∗[xeyezewe]
    过程被称为透视除法。要找到我们需要的矩阵P,我们需要利用两个关系:

    • 投影位置xpxp

    计算投影平面上的位置

    投影时原先位于相机坐标系中的点p=(xe,ye,ze)p=(xe,ye,ze)。具体过程如下图所示:
    投影平面上的点

    需要空间想象一下,可以得出左边的图是俯视图,右边是侧视图。
    利用三角形的相似性,通过俯视图可以计算得到:
    xpxe=nzexpxe=−nze

    由(1)(2)这个式子可以发现,他们都除以了ze−ze

    其中xpxp的映射关系如下图所示:

    投影点xp线性映射

    则可以得到xpxp

    由式子6可以得到:
    xc=2nrlxe+r+lrlze(1.6)(1.6)xc=2nr−lxe+r+lr−l∗ze

    对于ypyp

    展开全文
  • Qt坐标系统之窗口/视口变换原理

    千次阅读 2018-10-18 09:39:31
    Qt坐标变换原理之窗口/视口变换原理 若对C++语法不熟悉,建议参阅《C++语法详解》一书,电子工业出版社出版,该书语法示例短小精悍,对查阅C++知识点相当方便,并对语法原理进行了透彻、深入详细的讲解。 需要用到...

    Qt坐标系统之窗口/视口变换原理

    本文为原创文章,转载请注明出处,或注明转载自“黄邦勇帅(原名:黄勇)

    本文出自本人原创著作《Qt5.10 GUI完全参考手册》网盘地址:
    https://pan.baidu.com/s/1iqagt4SEC8PUYx6t3ku39Q
    《C++语法详解》网盘地址:https://pan.baidu.com/s/1dIxLMN5b91zpJN2sZv1MNg

    若对C++语法不熟悉,建议参阅本人所著《C++语法详解》一书,电子工业出版社出版,该书语法示例短小精悍,对查阅C++知识点相当方便,并对语法原理进行了透彻、深入详细的讲解,可确保读者彻底弄懂C++的原理,彻底解惑C++,使其知其然更知其所以然。此书是一本全面了解C++不可多得的案头必备图书。

    需要用到的QPainter类中的函数如下
    在这里插入图片描述
    1、理解“逻辑”
    “逻辑”一词具有“理论上的”意思,说简单一点,就是“假想的”
    2、从图形绘制的方向理解窗口和视口(原理见图12-60)
    在这里插入图片描述
    窗口就是一个逻辑上的(假想的)矩形,图形在这个假想的矩形上绘制,绘制完之后再把图形映射到视口上,视口通常是与需要显示的设备相关联的(即绘制设备,比如QWidget部件,显示屏等),然后图形才能显示出来。
    3、从图形显示方向理解窗口和视口(见图12-61)
    在这里插入图片描述
    假设需要显示图12-61中阴影部分的图形,则,首先把图形映射到窗口,此时可对图形进行旋转、缩放、平移等操作,然后把超出窗口之外的图形裁剪掉(这就是为什么窗口全称为裁剪窗口的原因),然后把图形映射到视口显示出来,若把视口理解为我们的眼睛,则视口和窗口的概念就很容易理解了。窗口的所有内容只有完全映射到了视口的范围内,才能被完全显示,一个窗口的内容可以同时映射到多个视口,即可以从不同的视口去观察窗口中的内容,在窗口到视口的映射过程中,还可对图形进行缩放、平移等简单变换。
    注意:此处讲解的只是一种理论模型,实际实现时是否会裁剪图形,以及坐标变换是在窗口进行还是在视口进行,则视实际使用的绘图软件而不同。
    4、窗口/视口主要作用
    绘制设备有以像素为单位的(比如显示器),也有以点为单位的(比如打印机),使用窗口/视口机制,可使绘图与绘制设备相互独立,我们只需在窗口绘图,而不必关心底层绘制设备到底是什么(即,不需关心底层设备究竟使用的什么单位等)。因为图形在窗口中绘制,因此窗口是来自真实世界的。
    5、窗口/视口变换公式的推导
    因为计算机中图形的绘制和显示通常都是位于矩形区域之内的,因此窗口/视口变换就是矩形到矩形的变换。
    窗口/视口变换原理(见图12-62):在窗口中被映射的点(x,y)与原点所围成的矩形区域,与被映射后在视口中的点(x’,y’)与原点所围成的矩形区域,其所对应的长度之比,应与窗口和视口所形成的矩形的长度之比相等,对于矩形区域的宽度,其原理相同。
    在这里插入图片描述
    为便于讲解引入表12-20所示变量及概念(意义见图12-62)
    在这里插入图片描述
    根据变换原理,变换后的点(x’,y’)可由如下公式计算得出(参见图12-62):
    在这里插入图片描述

    6、理解窗口/视口变换公式
    视口中的设备就是指的实际的绘制设备,设备坐标和设备点是不会变的,其位置通常被设置为绘制设备的左上角,方向是x轴从左向右,y轴从上到下增长。在视口中的坐标值x’,y’,Vox,Voy都是相对于设备坐标而言的,因此使用公式计算出来的坐标值x’,y’是相对于设备坐标而言的,因为窗口通常来自于现实世界,因此窗口中的坐标值是相对于世界坐标而言的。
    映射公式使用的数值是没有单位的,不存在某个数表示多少毫米,多少像素这一说法,计算时只需把相应的数值代入公式就能计算出正确的结果。
    7、窗口/视口变换可实现的坐标变换
    注意:以下的窗口和视口范围使用的数值并不是真实的数值,因为在坐标转换公式中,使用的是缩放系数(即他们的比值),因此使用真实数值并没有多大意义。
    在这里插入图片描述

    8、窗口/视口数据的单位(逻辑单位与设备单位)
    窗口和视口的数据在数学上来讲是没有什么实际意义的,数据就是一个数值,但在现实世界中绘制图形时,需要知道图形在绘图区域的具体位置,因此需要知道给定的数据具体表示多少个单位的距离,这样就需要给数据指定一个单位。比如,视口中的数据以“像素”为单位,窗口中的数据以“毫米”为单位等。
    视口数据的单位:来自视口的数据,一般都以实际的物理单位为单位,比如若视口为显示屏,若显示屏以像素为单位,则数据100表示位于显示屏100个像素处的实际位置,若显示屏以毫米为单位,则数据100表示位于显示屏100毫米处的实际位置。若视口中数据的意义未确定,则使用“设备单位”表示视口中数据的单位,比如100,表示100设备单位。
    窗口数据的单位:窗口的数据是实际绘制时希望使用的数据,因实际绘制时可能会使用多种不同的单位,因此在未明确窗口中数据的单位时,使用“逻辑单位”表示窗口数据的单位。比如若想以毫米为单位绘制图形,则1逻辑单位就是1毫米,若想以0.1毫米的精度绘制图形,则1逻辑单位就是0.1毫米。
    由以上可知,若想让绘制设备以实际窗口绘制时使用的逻辑单位为单位来显示图形,则在设备单位和逻辑单位之间需要一个单位转换,而这种转换可以使用窗口/视口变换来实现(详见下文)。
    数据的来源:由公式可知,x’,y’,Vex,Vey,Vox,Voy是来自视口的数据,因此这些数据是以设备单位为单位的,x,y,Wex,Wey,Wox,Woy是来自窗口的数据,这些数据是以逻辑单位为单位的。
    9、视口/窗口范围比Vex/Wex(缩放系数S)与单位转换
    对于缩放系数Vey/Wey=K的原理是相同的,仅以S为例讲解。
    实际绘制图形时,我们只需指定绘制时的单位,而不需关心物理设备究竟使用什么单位,比如想绘制100毫米长的直线,只需在绘制时直接输入100就能在物理设备上显示100毫米这么长的直线,而不是显示100像素或100点大小这么长的直线,这就是单位转换的问题,使用窗口/视口变换就能实现单位转换。
    虽然使用窗口/视口变换也可实现一些简单的坐标变换,但通常使用窗口/视口进行单位转换以实现在窗口中绘制的图形与现实世界相同,当然单位转换也可使用QTransform变换矩阵来完成。
    视口/窗口范围比在数据无任何单位时,就仅仅表示缩放系数,即Vex/Wex = S。
    视口/窗口范围比S的意义一般根据视口所表示的实际意义而定,下面以窗口的数据为未确定的逻辑单位,然后再依视口数据的单位不同,而分别对S的单位进行推导
    在这里插入图片描述

    10、单位转换示例
    例1:假设想以1逻辑单位表示0.1毫米,屏幕的分辨率为1024像素,屏幕实际长度为376mm,若客户区的长度为500像素,试确定窗口范围的尺寸,注意:屏幕是物理设备,是以像素为单位来绘制图形的。
    解:主要应注意单位间的转换,本示例只计算了X方向的情形,Y方向的情形未予计算。本示例的实际应用示例见示例12.24
    方法一:把单位转换为像素
    在这里插入图片描述
    方法二:把单位转换为毫米
    在这里插入图片描述

    示例12.24:使用窗口/视口变换实现以0.1毫米为单位在显示屏上绘制图形(结果见图12-63),本示例的显示屏尺寸及计算方法见例1的讲解
    void paintEvent(QPaintEvent *e){
        	QPainter pr(this);
        	QBrush bs(QColor(255,255,1));
    //绘制一个与视口一样大小的矩形,以便于观察
        	pr.drawRect(100,100,500,500);  
        	QPen pn;
        	pn.setColor(QColor(111,1,1));
        	pn.setWidth(10);
        	pn.setCapStyle(Qt::FlatCap);
        	pr.setPen(pn);
        	pr.setViewport(100,100,500,500);	//设置视口
        	pr.setWindow(0,0,1836,1836);	//设置窗口
    //注意:在设置窗口/视口之后,使用drawXXX绘制图形时使用的坐标,都需要使用公式26进行计算。
        	pr.drawLine(0,100,200,100);	}   //绘制一条长200*0.1mm(即20mm)长的直线
    

    在这里插入图片描述
    11、使用窗口/视口变换移动绘制设备的坐标
    由以上讲解可知,通过计算窗口/视口变换可实现绘制图形时以毫米、厘米等现实世界的单位为单位,下面再讲解一个使用窗口/视口变换实现移动绘制设备坐标的方法
    绘制设备的坐标默认位于左上角,但可通过窗口/视口变换在逻辑上来移动该坐标系到我们想要的位置。具体方法如下:
    使S = K = 1,即Vex = Wex; Vey =Wey; 也就是窗口和视口具有相同的宽度和长度,这意味着窗口和视口拥有相同的长度单位。此时,公式26变为
    x’=x+Vox-Wox; y’=y+Voy-Woy;
    以上公式是一个坐标平移公式,该公式不但是一个平移点的公式,也是平移坐标系的公式。因此该公式相当于把坐标系向x方向平移了Vox - Wox的距离,向y方向平移了Voy - Woy的距离。在之后绘制图形时可以以该坐标系为参考进行绘制。若绘图软件不裁剪图形,则可简单的把窗口/视口范围设置为1,即Vex = Wex = Vey = Wey =1。详见示例12.25

    示例12.25:移动绘制设备的坐标(结果见图12-64)
    void paintEvent(QPaintEvent *e){
        	QPainter pr(this);
    QBrush bs(QColor(255,255,1));
    //以下绘制的交叉直线用于标示平移后的
    //坐标位置,以方便观察
        	pr.drawLine(0,100,555,100);    
    pr.drawLine(100,0,100,555);
    //设置画笔
        	QPen pn;    pn.setColor(QColor(111,1,1));
       	pn.setWidth(10);pn.setCapStyle(Qt::FlatCap);
        	pr.setPen(pn);
    //设置窗口/视口,以下代码相当于把设备坐标移至(100,100)处,本示例也可把窗口/视口范围设置为1。
        		pr.setViewport(50,50,200,200);   pr.setWindow(-50,-50,200,200);
        	pr.drawLine(0,100,100,100);		pr.drawRect(-50,-50,100,100);}
    

    在这里插入图片描述

    本文作者:黄邦勇帅(原名:黄勇)

    在这里插入图片描述

    展开全文
  • 计算机图形学基础 视图变换:MVP变换、视口变换
  • 4.4 视口变换

    千次阅读 2015-05-26 15:04:16
    一、投影变换和视口变换 投影变换是将viewing frustum(视景体)变换为一个cuboid(立方体) 视口变换在投影变换之后,是将这个cuboid中的物体变换到视口中,见下图 二、视口变换 glViewport(GLint x,GLint y,...
  • 这篇是因为上一篇已经写太多了,而且几何变换和这两者也没有太大关系,所以分开来写,这篇主要总结投影变换、视口变换的原理以及对应的OpenGL函数。 ...
  • 视图变换,是指变换照相机的位置,角度。  模型变换,是指变换被照物体的位置,角度。 这两个变换,都会影响最终图形中,物体的位置,角度。而这两个变换,可以达到相同的效果。比如,你想要一个倒着的水杯图形,...
  • } void reshape(GLint newWidth, GLint newHeight) { /视口变换/ glViewport(0, 0, newWidth, newHeight); //定义视口大小 /*投影变换*/ glMatrixMode(GL_PROJECTION); glLoadIdentity(); /*透视投影,设置透视观察...
  • 视图变换(Viewing Transformation) 我们可以这样来描述视图变换的任务:将虚拟世界中以(x,y,z)为坐标的物体变换到 以一个个像素位置(x,y) 来表示的屏幕坐标系之中(2维),这确实是一个较为复杂的过程,但是整个...
  • 视口变换在投影变换之后,视口变换的作用是将投影平面上的点转换为屏幕上的点,这是一个缩放的过程。 投影变换的作用是将viewing frustum(视景体)中的场景投影到一个平面上,这个平面就是投影平面,在DirectX中,...
  • 写在前面 前面几节分别介绍了模型变换,视变换,本节继续学习OpenGL坐标变换过程中的投影变换。这里主要是从数学角度推导投影矩阵。对数学不感兴趣的,可以稍微了解下,或者跳过本节内容。...视口变换矩阵的推导 zF
  • The Model–View Transform(模型视口变换) In a simple OpenGL application, one of the most common transformations is to take a model from model space to view space so as to render it(在O...
  • OpenGL多视口变换函数:glViewport使用

    千次阅读 2015-11-07 13:49:16
    OpenGL多视口变换函数:glViewport使用 glViewport是OpenGL中的一个函数。计算机图形学中,在屏幕上打开窗口的任务是由窗口系统,而不是OpenGL负责的 1.功能glViewport在默认情况下,视口被设置为占据打开...
  • 本文主要翻译并整理自 songhoOpenGL Projection Matrix一文,这里对他的推导思路稍微进行了整理。 通过本节可以了解到 透视投影矩阵的推导 ... 视口变换矩阵的推导 zFighting问题 投影变换 OpenGL最...
  • 1、 模型变换和视图变换 从“相对移动”的观点来看,改变观察点的位置与方向和改变物体本身的位置与方向具有等效性。在OpenGL中,实现这两种功能甚至使用的是同样的函数。 由于模型和视图的变换都通过矩阵运算来...
  • OpenGL多视口变换函数:glViewport使用 glViewport是OpenGL中的一个函数。计算机图形学中,在屏幕上打开窗口的任务是由窗口系统,而不是OpenGL负责的 1.功能glViewport在默认情况下,视口被设置为...
  • 视口变换的矩阵求解

    2016-11-19 21:11:30
    视口变换在投影变换之后,投影变换是将viewing frustum(视景体)变换为一个cuboid(立方体),如下图 关于透视投影的矩阵求解,请参考透视投影详解 视口变换则是将这个cuboid中的物体变换到视口中,见下图 ...
  • 为什么80%的码农都做不了架构师?>>> ...
  • DirectX视口变换矩阵详解

    千次阅读 2013-12-23 23:05:29
    视口变换在投影变换之后,视口变换的作用是将投影平面上的点转换为屏幕上的点,这是一个缩放的过程。 投影变换的作用是将viewing frustum(视景体)中的场景投影到一个平面上,这个平面就是投影平面,在DirectX中,...
  • 这个步骤大致如下:一,把照相机固定在三脚架并让它对准场景(视图变换)二,把场景中的物体调整摆放好(模型变换)三,选择照相机的镜头,并调整放大倍数(投影变换)四,确定最终照片的大小(视口变换)。其中视图变换必须...
  • OpenGL视点变换,模型变换,投影变换,视口变换详解 作者:luck_net | 出处:博客园 | 2012/2/22 14:46:49 | 阅读112次 OpenGL通过相机模拟、可以实现计算机图形学中最基本的三维变换,即几何变换、投影...
  • 视口变换程序

    2007-11-29 11:05:10
    本软件可实现单视口到多视口变换
  • OpenGL中不设置模型,投影,视口,所绘制的几何图形的坐标只能是-1到1(X轴向右,Y轴向上,Z轴垂直屏幕)。 产生目标场景的过程类似于用照相机进行拍照: (1)把照相机固定在三角架上,并让他对准场景  从...
  •  从不同位置观察场景(视图变换) (2)对场景进行安排,使各个物体在照片中的位置是我们所希望的  移动,旋转或者放大缩小场景中的物体(模型变换) (3)选择照相机镜头,并调整放大倍数(调焦)  显示物体时...
  • 调用glViewPort函数来决定视见区域,告诉OpenGL应把渲染之后的图形绘制在窗体的哪个部位。当视见区域是整个窗体时,OpenGL将把渲染结果绘制到整个窗口。  glViewPort(x:GLInt;y:GLInt;Width:GLSizei;...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 8,376
精华内容 3,350
关键字:

视口变换