精华内容
下载资源
问答
  • 投影变换及坐标系统 官方说明数据 https://www.opengl.org/wiki/Main_Page 在OPENGL中采用是三维笛卡尔坐标系。 PC版本OpenGl支持多种多边形,但是在OpenGL ES下只支持三角形。 也就是说,所有图形都由...

    投影变换及坐标系统 官方说明数据   https://www.opengl.org/wiki/Main_Page

    在OPENGL中采用的是三维笛卡尔坐标系。

    PC版本OpenGl支持多种多边形,但是在OpenGL ES下只支持三角形。

    也就是说,所有图形都由三角形构建,类似积分的原理。

    在计算机图形学中有两种类型的投影方式:透视投影与正交投影。采用透视投影,物体越远越小,这样更接具真实性。正交投影往往用于2D绘制

    投影变换 在OpenGL中,如果想对模型进行操作,就要对这个模型的状态(当前的矩阵)乘上这个操作对应的一个矩阵.

    如果乘以变换矩阵(平移, 缩放, 旋转), 那相乘之后, 模型的位置被变换;

    如果乘以投影矩阵(将3D物体投影到2D平面), 相乘后, 模型的投影方式被设置;

    如果乘以纹理矩阵(), 模型的纹理方式被设置. 而用来指定乘以什么类型的矩阵, 就是glMatriMode(GLenum mode);

    glMatrixMode有3种模式: GL_PROJECTION 投影, GL_MODELVIEW 模型视图, GL_TEXTURE 纹理. 所以,在操作投影矩阵以前,需要调用函数:

    glMatrixMode(GL_PROJECTION); //将当前矩阵指定为投影矩阵

    然后把矩阵设为单位矩阵:

    glLoadIdentity();

    然后调用glFrustum()或gluPerspective(),它们生成的矩阵会与当前的矩阵相乘,生成透视的效果;

    有两种投影(透视投影及正射投影)。投影要在创建的时候设置。

    透视投影 一个函数:

    void glFrustum(GLdouble left,GLdouble Right,GLdouble bottom,GLdouble top,GLdouble near,GLdouble far);

    Ø  前四个参数是摄像头视口。正常情况是成比例的。

    Ø  第五个是近平面:可以认为近平面就对应着屏幕视口,不过近平面是Y向上,屏幕视口是Y向下。

    Ø  第六个是远平面:远平面的一个作用是做裁切用。只有在近平面,元平面之间的物体才被显示,超过的就裁切掉。

    创建一个透视型的视景体。其操作是创建一个透视投影的矩阵,并且用这个矩阵乘以当前矩阵。这个函数的参数只定义近裁剪平面的左下角点和右上角点的三维空间 坐标,即(left,bottom,-near)和(right,top,-near);最后一个参数far是远裁剪平面的离视点的距离值,其左下角点和 右上角点空间坐标由函数根据透视投影原理自动生成。near和far表示离视点的远近,它们总为正值(near/far 必须>0)。

    源代码: https://www.opengl.org/wiki/GluPerspective_code

    void glhFrustumf2(float *matrix, float left, float right, float bottom, float top,
                      float znear, float zfar)
    {
        float temp, temp2, temp3, temp4;
        temp = 2.0 * znear;
        temp2 = right - left;
        temp3 = top - bottom;
        temp4 = zfar - znear;
        matrix[0] = temp / temp2;
        matrix[1] = 0.0;
        matrix[2] = 0.0;
        matrix[3] = 0.0;
        matrix[4] = 0.0;
        matrix[5] = temp / temp3;
        matrix[6] = 0.0;
        matrix[7] = 0.0;
        matrix[8] = (right + left) / temp2;
        matrix[9] = (top + bottom) / temp3;
        matrix[10] = (-zfar - znear) / temp4;
        matrix[11] = -1.0;
        matrix[12] = 0.0;
        matrix[13] = 0.0;
        matrix[14] = (-temp * zfar) / temp4;
        matrix[15] = 0.0;
    }

    另一个函数:

    void gluPerspective(GLdouble fovy,GLdouble aspect,GLdouble zNear, GLdouble zFar);

    Ø  参数fovy定义视野在X-Z平面的角度,范围是[0.0, 180.0];

    Ø  参数aspect是投影平面宽度与高度的比率;

    Ø  参数zNear和Far分别是远近裁剪面沿Z负轴到视点的距离,它们总为正值。

    OpenGL的视角设定可以直接调用gluPerspective函数,但是OpenGL ES版本并不支持这个用法。ES的版本中只能支持glFrustum的函数调用。

    创建一个对称的透视型视景体,但它的参数定义于前面的不同,如图。其操作是
    创建一个对称的透视投影矩阵,并且用这个矩阵乘以当前矩阵。参数fovy定义视 野在Y-Z平面的角度,范围是[0.0, 180.0];参数aspect是投影平面宽度与高度的比率;参数Near和Far分别是近远裁剪面到视点(沿Z负轴)的距离,它们总为正值。

      以上两个函数缺省时,视点都在原点,视线沿Z轴指向负方向。

    void gluPerspective(
      GLdouble fovy, //角度
      GLdouble aspect,//视景体的宽高比
      GLdouble zNear,//沿z轴方向的两裁面之间的距离的近处
      GLdouble zFar //沿z轴方向的两裁面之间的距离的远处
      );


    在OPENGL中我们可以使用gluPerspective来设置视椎体。PC版的gluPerspective在OPENGL3.0以后就好像不见了。

    但是在OpenGLES中却没有提供这样的实用库支持,其实我们可以自己来完成这个函数的功能。代码如下:

    //matrix will receive the calculated perspective matrix.
    //You would have to upload to your shader
    // or use glLoadMatrixf if you aren't using shaders.
    void glhPerspectivef2(float *matrix, float fovyInDegrees, float aspectRatio,
                          float znear, float zfar)
    {
        float ymax, xmax;
        float temp, temp2, temp3, temp4;
        ymax = znear * tanf(fovyInDegrees * M_PI / 360.0);
        //ymin = -ymax;
        //xmin = -ymax * aspectRatio;
        xmax = ymax * aspectRatio;
        glhFrustumf2(matrix, -xmax, xmax, -ymax, ymax, znear, zfar);
    }

    正射投影 正射投影的最大一个特点是无论物体距离相机多远,投影后的物体大小尺寸不变。

    函数:

    void glOrtho(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top, GLdouble near,GLdouble far)

    六个参数, 前两个是x轴最小坐标和最大坐标,中间两个是y轴,最后两个是z轴值

    它创建一个平行视景体(就是一个长方体空间区域)。

    实际上这个函数的操作是创建一个正射投影矩阵,并且用这个矩阵乘以当前矩阵。

    其中近裁剪平面是一个矩形,矩形左下角点三维空间坐标是(left,bottom,-near),

    右上角点是(right,top,-near);远裁剪平面也是一个矩形,左下角点空间坐标是(left,bottom,-far),右上角点是(right,top,-far)。

    注意,所有的near和far值同时为正或同时为负, 值不能相同。如果没有其他变换,正射投影的方向平行于Z轴,且视点朝向Z负轴。这意味着物体在视点前面时far和near都为负值,物体在视点后面时far和near都为正值。

    只有在视景体里的物体才能显示出来。

    如果最后两个值是(0,0),也就是near和far值相同了,视景体深度没有了,整个视景体都被压成个平面了,就会显示不正确。


    设置视图变换(Setting the View Transform) 设置视图矩阵最简单的方法就是用LookAt方法,它并不是OpenGL ES的内置函数,但是可以自已快速实现。它有三个参数:相机位置,目标位置,一个”up”向量表示相机朝向>

    通过三个向量的传入,LookAt就可以生成一个变换矩阵,否则就得用基本的变换(缩放,移动,旋转)来生成。

    一个参考的 LookAt函数

    mat4 LookAt(const vec3& eye, const vec3& target, const vec3& up)

    {

    vec3 z = (eye – target).Normalized(); vec3 x = up.Cross(z).Normalized(); vec3 y = z.Cross(x).Normalized();

    mat4 m;

    m.x = vec4(x, 0);

    m.y = vec4(y, 0);

    m.z = vec4(z, 0);

    m.w = vec4(0, 0, 0, 1);

    vec4 eyePrime = m * -eye; m = m.Transposed();

    m.w = eyePrime;

    return m;

    }



    一旦设置了设影矩阵, 就设定了视野。视锥表示眼在金字塔顶部的一个锥体。

    基于金字塔的顶点(称为视野)的角度,可以计算一个视锥。开发者认为这样比指定六面更加直观。示例2.2中方法有四个参数:视角,金字塔宽高比,远与近裁剪面。

    示例方法有四个参数:视角,金字塔宽高比,远与近裁剪面。

    void VerticalFieldOfView(float degrees, float aspectRatio, float near, float far)

    {

         float top = near * std::tan(degrees * Pi / 360.0f);

         float bottom = -top;

         float left = bottom * aspectRatio;

         float right = top * aspectRatio;

        

         glFrustum(left, right, bottom, top, near, far);

    }


    转自:http://iteches.com/archives/44016


    展开全文
  • 记录通过2D或3D投影变换分隔图像对。 1对图像拼接 第一步是编写代码以将一对图像拼接在一起。 对于这一部分,您将继续工作 与以下一对(单击图像以下载高分辨率版本): 1.加载两个图像,将其转换为两倍和灰度。 2...
  • 有趣各种投影方式

    千次阅读 2017-08-05 18:09:39
    摄像机设置 投影方式 基本变换

    • 摄像机的设置

    若摄像机位置、姿态不同,对同一场景进行拍摄,得到的画面也是迥然不同的。

    可通过Matrix类的setLookAtM方法来完成对摄像机的设置。

    setLookAtM方法的功能为根据接收的9个摄像机相关参数产生摄像机的观察矩阵,并将矩阵的元素填充到指定数组中。

     Matrix.setLookAtM(mVMatrix,0,cx,cy,cz,tx,ty,tz,upx,upy,upz);
    mVMatrix 存储生成矩阵元素的float[]类型数组;

    0 : 填充起始偏移量;

    cx,cy,cz : 摄像机位置的x,y,z坐标;

    tx,ty,tz : 观察目标点的x,y,z坐标;

    有了位置和朝向,此时摄像机可以360度旋转,这时我们需要一个up方向,将摄像机固定在一个位置一个方向。

    upx,upy,upz : up向量在x,y,z轴上的分量;

    • 投影方式

    投影方式有两种,分别是正交投影和透视投影

    -- 视景体 : OpenGL ES 2.0中,管线会确定的一个可视空间区域, 由 上平面(up), 下平面(down), 左平面(left), 右平面(right), 远平面(far), 近平面(near) 六个平面组成;

    -- 视景体与投影 : 视景体内的物体会投影到近平面, 然后再将近平面上投影出的内容映射到屏幕上的视口中, 视景体之外的内容会被裁减掉, 例如眼睛看不到的范围就是处于视景体外即被裁减掉的;

    一、正交投影 

    正交投影属于平行投影, 投影线平行, 视景体是长方形的, 投影的内容不会出现近大远小的效果;
    可通过Matrix类的orthoM方法来完成对正交投影的设置。
     Matrix.orthoM(mProjMatrix, 0, left, right, bottom, top, near, far);
    mProjMatrix 存储生成矩阵元素的float[]类型数组;

    0 : 填充起始偏移量;

    left, right : near面的left、right 对应的x坐标;

    bottom, top : near面的bottom、top 对应的y坐标;

    near, far : near面、far面与视点的距离;

    二、透视投影

    透视投影与现实世界观察物体一样, 有近大远小的效果, 这种投影更加真实;
    可通过Matrix类的orthoM方法来完成对正交投影的设置。
     Matrix.frustumM(mProjMatrix, 0, left, right, bottom, top, near, far);
    mProjMatrix : 存储生成矩阵元素的float[]类型数组;

    0 : 填充起始偏移量;

    left, right : near面的left、right 对应的x坐标;

    bottom, top : near面的bottom、top 对应的y坐标;

    near, far : near面、far面与视点的距离;
    一般情况下,应该保证近平面的宽高比与视口的宽高比相同,否则显示在屏幕上的图像会拉伸变形。
    -------------------------------------------------------------------------------------------------------------------

    一般情况下,应该保证近平面的宽高比与视口的宽高比相同,否则显示在屏幕上的图像会拉伸变形。

    -------------------------------------------------------------------------------------------------------------------

    • 各种变换
    变换有三种基本变换,分别是平移、旋转、缩放


    currMatrix是当前变换矩阵

    一、平移 

    Matrix.translateM(currMatrix, 0, x, y, z);
    沿x轴方向平移x,沿y方向平移y,沿z方向平移z

    二、旋转 

    Matrix.rotateM(currMatrix, 0,angle, x, y, z);
    绕与x,y,z方向相同的轴旋转angle度

    三、缩放 

    Matrix.scaleM(currMatrix, 0, x, y, z);
    沿x轴方向按x倍缩放,沿y轴方向按y倍缩放,沿z轴方向按z倍缩放


    展开全文
  • 几何变换的基本概念 对原始图像,按照需要改变其大小、形状和位置的变化 ...二维图像几何变换的基本方式 多项式变换、透视变换 多项式变换 透视变换 以上图片来自 刘定生 中科院对地观测与数字

    几何变换的基本概念
    对原始图像,按照需要改变其大小、形状和位置的变化
    变换的类型:二维平面图像的几何变换、三维图像的几
    何变换、由三维向二维平面的投影变换等
    二维图像几何变换的定义
    对于原始图像f(x,y),坐标变换函数
    x’ = a(x,y); y’ = b(x,y)
    唯一确定了几何变换:
    g(x’,y’) = f(a(x,y), b(x,y)) g(x,y)是目标图像
    二维图像几何变换的基本方式
    多项式变换、透视变换
    多项式变换在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    透视变换在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    以上图片来自 刘定生 中科院对地观测与数字地球科学中心 图像处理课件

    展开全文
  • 在这一节中,我们将一步步从基础构起,完成由3D物体坐标转换为到屏幕上所看到图像的变换流程,最终反映在程序中便是我们输入三位点依据我们设置观察方式投影到了屏幕上。这部分内容可以参考《计算机图形学》...

    说明

    在这一节中,我们将一步步的从基础构起,完成由3D物体坐标转换为到屏幕上所看到的图像的变换流程,最终反映在程序中便是我们输入的三位点依据我们设置的观察方式投影到了屏幕上。这部分内容可以参考《计算机图形学》第四版。

     

    首先明白几个概念。

    1.    模型坐标系,在此坐标系下构建我们的3D物体(一般以物体几何中心为坐标中心)。

    2.    世界坐标系,拥有所有3D物体的整个3D世界。

    3.    相机坐标系,该坐标系是以观察用相机(我们眼睛)为中心。

    4.    裁剪空间,我理解为我们所划定的能观察到的相机坐标系中的部分,其实还在相机坐标系中

    5.    标准设备空间,我理解为我们最终投影到的位置在【-1,1】之间。

    6.    屏幕空间,将【-1,1】映射到屏幕的大小下。

     

    整个转换流程是

     

    其中裁剪空间我们在透视矩阵中即可设置,表现为一个可视截楔形台。

    具体看下面的流程

    我们此时所处为相机空间,也就是说当一个点x==0,y==0时应在屏幕中心,但是由于人眼的透视效果,我们不可只用x与y来确定一个物体应放在屏幕哪部分,所以使用到相机的距离Z,当一点x,y坐标相等,我们依据Z来判断哪一个更应放在屏幕中。

     

     

    借助图形,在投影前,蓝色为世界坐标系中物体,红色部分为相机视角下能看见的地方。

     

    对物体使用透视矩阵后

    每一个锥台都是一个原先的立方体透视变换后,也就是符合近大远小的原则。

    实际看来就是下面样子

     

     

    代码简介

    Vector4D(PointerD),Mat(4*4矩阵),这两个类来进行基本数学表示,其中若用到Point2D,则采用Point4D来模拟。并附有加减乘除,向量积与数量积等运算。(基本线性代数)

     

    Camera:

    观察相机相关,设置视图矩阵

     

    Transform:

    包含从模型到世界到相机再到投影平面变换过程的综合变换矩阵。

    在这里设置透视矩阵(推导参考重要矩阵部分)

     

    Device:

    综合渲染过程。

     

     

    部分系统调用代码(窗口创建,显示framebuffer等),这一部分不必深究,因为其实它不是我们的软渲染器的核心部分,只是辅助而已,我们只要会访问其中的显示缓存framebuffer即可。

     

    代码执行流程为:

     

    Main {

           初始化模型mesh;

           设置windows窗口;

           实例化设备并与窗口的显示缓存绑定;

           初始化相机。

           设置模型变换的变换矩阵的视图矩阵与透视矩阵;

          

    While {

           窗口相关;

           设备显示内存清空;

           设备渲染模型;

           调整模型姿态;

           更新窗口画面;

           Sleep(1);

    }

    }

     

    Code:

    All1.h

    Main.cpp

     

    PS:

    之前看计算机图形学的时候,那时感觉这一套变换流程不是很难嘛,但是今天具体实现时发现许多细节要注意。

     

     

    重要矩阵

    平移旋转缩放矩阵

    变换矩阵(可以是平移、旋转、缩放矩阵或者他们的组合)

    使用方式:变换矩阵 * 某一点 = 变换后的点

     

     

    平移矩阵:

     

     

    缩放矩阵:

     

    x, y, z 分别表示希望x, y,z 上的缩放倍数。

     

    旋转矩阵:

     

    对于任意轴p时,可将旋转分解为

    1.将坐标轴旋转,使旋转轴p与Z轴重合

    2.将点w绕Z轴旋转theta度

    3.再将坐标轴旋转回原位。

    即:

     

     

    Point_after = Rz(ψ)*Ry(ϕ)*Rz(θ)*Ry(−ϕ)*Rz(−ψ)*Point_before

    其中借助旋转矩阵作为正交矩阵的特点用 R(−α)=(R−1)(α)=RT(α)

    简化为

    (正交证明:http://blog.csdn.net/zhang11wu4/article/details/49761121

    Rz(ψ)*Ry(ϕ)*Rz(θ)*RyT(ϕ)*RzT(ψ)

    计算后可得:(x,y,z)为旋转轴单位向量,theta为弧度制旋转角

     

    对一个点做变换,大部分为平移旋转与缩放的集合,所以可以将变换矩阵利用矩阵性质组合起来,即:Mat = translation_mat * rotate_mat * scale_mat

    Point_after = Mat * Point_before  (先缩放,后旋转,然后平移)

    Reference:

    http://blog.csdn.net/csxiaoshui/article/details/65446125

    视图矩阵

    在这里的是

    1、首先我们来求得N = eye – lookat(/*其实这里依据左手坐标系,应为lookat-eye,但因为下图中画出的方向一致性,这里写为eye –lookat,最终使用时记得换回来*/),并把N归一化。

    2、up和N差积得到U, U= up X N,归一化U。

    3、然后N和U差积得到V

     

     

     

     

    假设一开始相机坐标系和世界坐标系重合,它先进行一个旋转变化,然后再进行一个平移,得到现在是相机位置和方位。则此时进行的矩阵变化为

    ,其中T是平移变化,R是旋转变化,而相机变换是相机本身变换的逆变换。

     

    T的逆矩阵为:

     

    当相机完成自身坐标系原点移至世界坐标系原点一步之后,相机的原点和世界原点就重合了,也就是处理完了关于平移的变换。

       我们要把一个世界坐标系点K(Kx, Ky, Kz),表示成(U,V,P)坐标系的点(假设此时,已经经过平移操作,摄像机在世界坐标系的原点),则其公式为:

    Lx = Kx * Ux + Ky * Uy +Kz * Uz;

    Ly = Kx * Vx + Ky * Vy +Kz * Vz;

    Lz = Kx * Px + Ky * Py +Kz * Pz;

    即:

     

     

     

    Reference:

    https://blog.csdn.net/tangguotupaopao/article/details/26477533

    http://www.cnblogs.com/mikewolf2002/archive/2012/03/11/2390669.html

    http://blog.csdn.net/augusdi/article/details/20450065

    http://www.cnblogs.com/mikewolf2002/archive/2012/11/25/2787636.html

     

    Code:

     

    void Mat::Set_As_Rotate(float x, float y,floatz, float theta) {

        //设置为旋转矩阵

        //theta是弧度值

        float qsin = (float)sin(theta);

        float qcos = (float)cos(theta);

        float one_qcos = 1 -qcos;

        Vector4D vi(x,y,z, 1);

        vi.Normalize();

        float X = vi.x, Y = vi.y,Z = vi.z;

        m[0][0]= qcos + X*X*one_qcos;

        m[0][1]= X*Y*one_qcos - Z*qsin;

        m[0][2]= X*Z*one_qcos + Y*qsin;

        m[0][3]= 0.0f;

        m[1][0]= Y*X*one_qcos + Z*qsin;

        m[1][1]= qcos + Y*Y*one_qcos;

        m[1][2]= Y*Z*one_qcos - X*qsin;

        m[1][3]= 0.0f;

        m[2][0]= Z*X*one_qcos - Y*qsin;

        m[2][1]= Z*Y*one_qcos + X*qsin;

        m[2][2]= qcos + Z*Z*one_qcos;

        m[2][3]= 0.0f;

        m[3][0]= 0;

        m[3][1]= 0;

        m[3][2]= 0;

        m[3][3]= 1.0f;

    }

     

     

     

     

     

    透视矩阵

     

    说了这么多,透视矩阵到底怎么做的?

    视锥体:

    视锥体是一个三维体,他的位置和摄像机相关,视锥体的形状决定了模型如何从camera space投影到屏幕上。最常见的投影类型-透视投影,使得离摄像机近的物体投影后较大,而离摄像机较远的物体投影后较小。透视投影使用棱锥作为视锥体,摄像机位于棱锥的椎顶。该棱锥被前后两个平面截断,形成一个棱台,叫做View Frustum,只有位于Frustum内部的模型才是可见的。

     

    透视投影的目的:

    透视投影的目的就是将上面的棱台转换为一个立方体(cuboid),转换后,棱台的前剪裁平面的右上角点变为立方体的前平面的中心(下图中弧线所示)。由图可知,这个变换的过程是将棱台较小的部分放大,较大的部分缩小,以形成最终的立方体。这就是投影变换会产生近大远小的效果的原因。变换后的x坐标范围是[-1, 1],y坐标范围是[-1, 1],z坐标范围是[-1, 1]。

     

     

    透视投影矩阵推导:

    那么透视投影到底做了什么工作呢?

    我们可以将整个投影过程分为两个部分,第一部分是从Frustum内一点投影到近剪裁平面的过程,第二部分是由近剪裁平面缩放的过程。假设Frustum内一点P(x,y,z)在近剪裁平面上的投影是P'(x',y',z'),而P'经过缩放后的最终坐标设为P''(x",y",z")。假设所求的投影矩阵为M,那么根据矩阵乘法可知,如下等式成立。

     

    先看第一部分,为了简化问题,我们考虑YOZ平面上的投影情况,见下图。设P(x, y, z)是Frustum内一点,它在近剪裁平面上的投影是P'(x', y', z')。(注意:D3D以近剪裁平面作为投影平面),设视锥体与Z轴夹角。

     

     由上图可知,三角形OP'Q'与三角形OPQ相似,于是有如下等式成立。

     

    又因为投影平面的宽长比为Aspect,所以

     即:

     

    由W/H = Aspect

     

    此图问题应为除

    最后看z'',当Frustum内的点投影到近剪裁平面的时候,实际上这个z'值已经没有意义了,因为所有位于近剪裁平面上的点,其z'值都是n,看起来我们甚至可以抛弃这个z'值,可以么?当然不行!别忘了后面还有深度测试呢。由第一幅图可知,所有位于线段p'p上的点,最终都会投影到p'点,那么如果这条线段上真的有多个点,如何确定最终保留哪一个呢?当然是离观察这最近的这个了,也就是深度值(z值)最小的。所以z'坐标可以直接保存p点的z值。因为在光栅化之前,我们需要对z坐标的倒数进行插值(原因请参见Mathematics for 3D Game Programming and Computer Grahpics 3rdsection 5.4),所以可以将z''写成

     

     

     

    将X”Y”Z”代入最开始矩阵乘法等式

     

    由上式可见,x'',y'',z''都除以了Pz,于是我们将他们再乘以Pz(这并不该变齐次坐标的大小),得到如下等式。

     

    注意这里,x即Px,y即Py,z即Pz,解矩阵的每一列得到

     

    于是所求矩阵为

     

    注意,这里推得的透视变换矩阵是右乘用 即Vec_before*Mat= Vec_after

     

    Reference:

    https://blog.csdn.net/tangguotupaopao/article/details/26477533

    http://www.cnblogs.com/caster99/p/4783386.html

    http://www.cnblogs.com/graphics/

    http://www.cnblogs.com/zhangbaochong/p/5388792.html

    Code:

    void Transform::Init(int width, int height) {

        // 初始化,设置屏幕长宽

     

        world.Set_Identity();

        view.Set_Identity();

        w= (float)width;

        h= (float)height;

    }

     

    void Transform::Set_Perspective(float fovy, float aspect,floatzn, float zf) {

        //设置透视矩阵,相当于D3DXMatrixPerspectiveFovLH

        //fovy = view frustum 与Z轴夹角弧度制

        //aspect 投影面宽长比(显示区宽长比)

        //zn 相机到近裁剪平面距离,zf相机到远裁剪平面距离

     

        float fax = 1.0f / (float)tan(fovy * 0.5f);

        projection.Set_Zero();

        projection.m[0][0]= (float)(fax /aspect);

        projection.m[1][1]= (float)(fax);

        projection.m[2][2]= zf / (zf -zn);

        projection.m[2][3]= zn * zf / (zn - zf);

        projection.m[3][2]= 1;

        /*projection.m[3][2] = zn * zf / (zn - zf);

        projection.m[2][3]= 1;*/

    }

     

     

    void Transform::Update() {

        // 矩阵更新,计算 transform =   projection * view * world

        static Mat m;

        m.Set_Identity();

        view.Mul(world,m);

        projection.Mul(m,transform);

    }

    void Transform::Apply(Vector4D &op,Vector4D &re) {

        //old  将矢量 op进行 project

        //此操作后,re里的x,y即为在屏幕中显示的位置,z留作深度测试

        transform.Mul_Vec(op, re);

     

    }

    void Transform::Homogenize(Vector4D &op,Vector4D &re) {

        // 归一化,得到屏幕坐标

        float rhw = 1.0f / op.w;

        re.x = (op.x * rhw + 1.0f) * w* 0.5f;

        re.y = (1.0f - op.y * rhw) * h *0.5f;

        re.z = op.z * rhw;

        re.w = 1.0f;

    }

     

     

    展开全文
  • 透视投影是3D渲染的基本概念,也是3D程序设计的基础。掌握透视投影的原理对于深入理解其他3D渲染管线具有重要作用。本文详细介绍了透视投影的原理和算法实现,包括透视投影的标准模型、一般模型和屏幕坐标变换等,并...
  • 墨卡托投影的应用

    2019-11-27 17:22:53
    传统在三维球上绘制一个对象, 比如说 圆形、圆锥等,常用的方式是绘制一个局部圆等对象 ,然后经过mvp投影变换放到指定地理位置处,当然这样也有很多好处,比如说动态变化时,只需要更新下投影变换矩阵,不用重新...
  • 空间几何变换系统.m

    2021-01-29 16:23:02
    初学数字图像,包含图像导入,导出,基本空间变换如平移,旋转,缩放,剪切,投影,仿射变换投影和放射都只有一种实现方式】,仅用于实验报告。 自学Matlab GUI编程,设计并实现一个图像空间变换系统要求: 1、能...
  • 利用频域内傅里叶投影变换定理,提出优化有限拉东(Radon)变换系数顺序方法,使得拉东变换后图像折回现象得到改善;利用广义模糊集合概念和最大模糊熵原理,提出一种自适应设置模糊增强函数方法,使得增强后图像在...
  • opengl 矩阵变换

    2010-11-01 15:28:00
    第四章 矩阵变换  通过前三章学习,我们...你可以对投影方式进行变换,也可以对物体/模型 进行变换。你可以改变自己位置和方向,也可以改变物体大小和角度。学习本章内容,你将了解: OpenGL中
  • 计算机图形学基础-三维变换

    千次阅读 2016-07-29 12:05:30
    变换是计算机图形学中重要概念,包括最基本的三维变换,即几何变换、投影变换、裁剪变换、视口变换。 1.从三维空间到二维平面   1.1 相机模拟  在真实世界里,所有物体都是三维。但是,这些三维...
  • 6 3D变换介绍 以上通过简单地复制OpenGLDemo中的...OpenGL中的基本变换方式有视图变换、模型变换、投影变换和视口变换等。简单的说,视图变换相当于设置观察点位置和方向,模型变换相当于改变模型的大小、位置、方...
  • 变换是计算机图形学中重要概念,包括最基本的三维变换,即几何变换、投影变换、裁剪变换、视口变换。 1.从三维空间到二维平面 1.1 相机模拟 在真实世界里,所有物体都是三维。但是,这些三维物体在计算机...
  • 在前面博客中,所有例子都是一个...什么是矩阵其实在之前博客中,我们也基本都用到了矩阵,投影的设置,就是根据参数生成一个4*4矩阵,我们用长度为16浮点型数组来存储,相机设置也是如此。那么矩阵到底该

空空如也

空空如也

1 2 3 4 5 ... 10
收藏数 191
精华内容 76
关键字:

投影变换的基本方式