基本知识

右手坐标系

右手手掌弯曲,手指方向由正X轴指向正Y轴,如果这时Z轴正方向与大拇指方向保持一致,坐标系为右手坐标系,否则为左手坐标系。

向量叉乘的方向

向量(1,0,0)与向量(0,1,0)叉乘的结果可以由公式计算得到为(0,0,1),在数值上它是始终不变的。但放在坐标中进行解释,(0,0,1)都是代表Z轴正方向,但在左右手坐标系中他们与X,Y轴正方向的相对空间位置是不同的。在右手坐标中判断叉乘结果的方向使用右手定律,左手坐标系中使用左手。

视图变换是三维渲染中物体顶点坐标变换的一部分,完整的流程为:

1使用Module矩阵将物体顶点坐标从物体坐标系转换至世界坐标系

2使用View矩阵将物体顶点坐标从世界坐标系转换至由摄像机定义的坐标系,摄像机坐标系原点在摄像机,Z轴方向沿着视线方向往前,y轴方向即摄像机的向上向量。

3.使用透视投影矩阵及透视除法将位于视锥体内的顶点坐标转换到X,Y,Z范围都为-1至1.

摄像机特点:

三维自由运动的物体有六个运动自由度,分别是X,Y,Z方向的平移和绕X,Y,Z轴的选择。绕Z轴的旋转使物体发生侧向倾斜,如果站在人的角度考虑的话,就是向左或向右倾斜了,这个自由度在大部分情况是可以不要的,他更容易使人产生眩晕感。所以这里的摄像机拥有剩余的五个自由。绕X轴选择代表了仰视和俯视,绕Y轴旋转代表了旋转自身,比如从向东旋转到向西。

View矩阵的工作原理

View矩阵的工作目标是将世界坐标系中的所有物体的顶点的坐标从世界坐标系转换到摄像机坐标系。

摄像机坐标系的原点不一定与世界坐标系重合,同时由于自身的旋转,坐标轴也一定不与世界坐标系的坐标轴平行。为完成工作任务,需要分为两步走1.整体平移,将摄像机平移至世界坐标系原点,2.将坐标点从世界坐标系转换至摄像机坐标系。

使用单位向量U,V,W分别代表摄像机坐标系X,Y,Z轴正向的单位向量在世界坐标系中的表示,则在摄像相机坐标系与世界坐标系原点重合的情况下,物体顶点坐标代表的向量(即从世界原点指向物体顶点的向量)在U,V,W上的投影大小即是物体顶点在摄像机坐标系下的坐标值。因为U,V,W是单位向量,使用二者的点乘即可以得到顶点的投影大小。

Lookat函数的一般形式

LookAt(Vector3 eyePos,Vector3 targerPos,Vector3 upDir,Matrix4 & ViewMatrix);

函数的参数:eyePos代表了摄像机在世界坐标系中的坐标,targetPos代表了视线方向上某个目标物体的坐标,upDir一般使用的是世界坐标系中的向上向量,即(0,1,0).

这个函数将传入的最后一个参数设置为前面参数所指定的View矩阵。

首先要先求得摄像机坐标系的U,V,W。

1.首先已知eyePos和tarPos,可以求得视线方向,视线方向由eyePos指向tarPos,所以viewDir=tarPos-eyePos,W=viewDir.normalize()

2.U=crossProduct(upDir,W) U=U.normalize()

upDir一般是向量(0,1,0),所以求得的U向量必然是平行于地面,而如果物体绕Z轴选择,X轴将不再平行于地面。说明使用upDir为(0,1,0)时计算U,V,W的计算方法默认摄像机只有两个旋转自由度。

3.V=crossProduct(W,U) V.normalize()

注意:这里使用右手坐标系,使用向量叉积计算U,V时,crossProduct()函数的参数的顺序是重要的。叉乘结果向量的方向符合右手法则。

现在View矩阵可以由两个矩阵合成,一个是将摄像机平移至原点的矩阵T,一个是将坐标点从世界坐标系转换至摄像机坐标系的矩阵R。

 

大概的代码表示的流程

 void Matrix4X4::initLookAtMatrix(const Vector3& eyePos, const Vector3& targetPos, const Vector3& updir) {
Vector3 eye = eyePos;
Vector3 tar = targetPos;
Vector3 up = updir; Vector3 W = tar - eye;
W.normalize();
Vector3 U = Vector3::crossProduct(up, W);
U.normalize();
Vector3 V = Vector3::crossProduct(W, U);
V.normalize(); float m[][] = { { U.x,U.y,U.z, },{ V.x,V.y,V.z, },{ W.x,W.y,W.z, },{ ,,, } };
Matrix4X4 coordiTransformMatrix(m); Matrix4X4 contraryTranslation;
contraryTranslation.initTranslationMatrix(-eyePos.x, -eye.y, -eye.z); *this = coordiTransformMatrix*contraryTranslation; }

右手坐标系下LookAt视图矩阵的推导的更多相关文章

  1. 视图矩阵的推导-opengl应用

    把物体从世界坐标系转化到视点坐标系的矩阵称为视图矩阵. 下面我们先看下opengl视图矩阵的推导过程: 假设视点或camera的局部坐标系为UVN,UVN分别指向右方.上方和后方从而构成右手坐标系,视 ...

  2. (转)投影矩阵的推导(Deriving Projection Matrices)

    转自:http://blog.csdn.net/gggg_ggg/article/details/45969499 本文乃<投影矩阵的推导>译文,原文地址为: http://www.cod ...

  3. WEBGL学习【四】模型视图矩阵

    <html lang="zh-CN"> <!--服务器运行地址:http://127.0.0.1:8080/webgl/LearnNeHeWebGL/NeHeWe ...

  4. OpenGL(五) 三维变换之模型视图矩阵

    计算机三维图形学中,一个基本的任务是如何描述三维空间中一个物体位置的变化,也就是如何 描述物体的运动.通常情况下,物体位置的变化包含三个基本的变化:平移.旋转和缩放,物体的运动也可以用这三个基本的运动 ...

  5. 3D中的相机 - 投影矩阵和视图矩阵

    3D中的相机 - 投影矩阵和视图矩阵 3d游戏中,一般通过相机的设置来计算投影矩阵和视图矩阵,比如untiy和cocos,一般情况下我们不用关注如何计算, 可以直接在可视化的编辑器中调整参数就可以了, ...

  6. 解决Oracle在scott用户下创建视图(VIEW)权限不足的方法

    问题描述:在scott用户下创建视图的时候,报错:权限不足.(其他用户以此类推)解决方法: 以dba用户登录 sqlplus / as sysdba 赋予scott用户创建VIEW的权限 grant  ...

  7. UFLDL深度学习笔记 (二)SoftMax 回归(矩阵化推导)

    UFLDL深度学习笔记 (二)Softmax 回归 本文为学习"UFLDL Softmax回归"的笔记与代码实现,文中略过了对代价函数求偏导的过程,本篇笔记主要补充求偏导步骤的详细 ...

  8. OpenGL中投影矩阵的推导

    本文主要是对红宝书(第八版)第五章中给出的透视投影矩阵和正交投影矩阵做一个简单推导.投影矩阵的目的是:原始点P(x,y,z)对应后投影点P'(x',y',z')满足x',y',z'∈[-1,1]. 一 ...

  9. [OpenGL](翻译+补充)投影矩阵的推导

    1.简介 基本是翻译和补充 http://www.songho.ca/opengl/gl_projectionmatrix.html 计算机显示器是一个2D的平面,一个3D的场景要被OpenGL渲染必 ...

随机推荐

  1. GBDT+Lr

    https://blog.csdn.net/shine19930820/article/details/71713680 http://scikit-learn.org/stable/auto_exa ...

  2. linux软连接(转)

    这是linux中一个非常重要命令,请大家一定要熟悉.它的功能是为某一个文件或目录在另外一个位置建立一个同步的链接,类似Windows下的超级链接. 这个命令最常用的参数是-s,具体用法是:sudo l ...

  3. cv2.SIFT() AttributeError: 'module' object has no attribute 'SIFT' OpenCV Python can't use SURF, SIFT

    参考链接: https://stackoverflow.com/questions/18561910/opencv-python-cant-use-surf-sift For recent infor ...

  4. numpy 矩阵变换 reshape ravel flatten

    1. 两者的区别在于返回拷贝(copy)还是返回视图(view),numpy.flatten()返回一份拷贝,对拷贝所做的修改不会影响(reflects)原始矩阵,而numpy.ravel()返回的是 ...

  5. springMVC :interceptors

    1.配置拦截器 在springMVC.xml配置文件增加:     <mvc:interceptors>    <!-- 日志拦截器 -->    <mvc:interc ...

  6. 消息队列RabbitMQ与Spring

    1.RabbitMQ简介 RabbitMQ是流行的开源消息队列系统,用erlang语言开发.RabbitMQ是AMQP(高级消息队列协议)的标准实现. 官网:http://www.rabbitmq.c ...

  7. Computed property names

    [Computed property names] That allows you to put an expression in brackets [], that will be computed ...

  8. Brainwashing

    [Brainwashing] 1.教育和媒体都是“国家意识机器”,他们维持并复制国家领导者的思想. 2.洗脑.情感.意识. 3.洗脑所产生的各种影响具有如下特征:全用暴力,或者进行欺骗,或二者兼有. ...

  9. Python爬虫使用MD5加密的坑

    由于公司的业务需要,需要爬取很多的国外网站图片,然后兄弟我一路正则杀过去,总共匹配到658张链接,心里美滋滋开始写下载的代码.然后就有了这次坑的记录. 首先这是我查到的链接数量 然后爬虫跑完后,美滋滋 ...

  10. Jenkins安装部署(二)

    Jenkins配置 一.修改jenkins家目录 由于jenkins在启动个之后会默认将所有的构建应用在家目录中创建一遍,为了合理化服务器资源,重新定义jenkins家目录. 在tomcat的cata ...