码迷,mamicode.com
首页 > 其他好文 > 详细

对相机的理解及使用多相机绘制只旋转的坐标系

时间:2016-09-30 15:14:19      阅读:363      评论:0      收藏:0      [点我收藏+]

标签:

1. 对相机的理解

1.1. 点是怎么转到屏幕上

假设一个A点在世界坐标系内的坐标是A(x, y, z), 视口矩阵,投影矩阵,模型视图矩阵为M, N, P,则 M* N * P * A = A1,  A1就是点A在屏幕上的坐标。有此可见,在这个过程中只有三个矩阵M,N,P,而没有相机的概念,所谓相机的概念其实是对矩阵M, N, P的一种解释方式,只不过这种解释方式比较形象,容易理解,容易使用。但是除了用相机去解释这三个矩阵,其实还有其它很多解释方式,就像一种颜色在正常人的眼里和色盲的眼里是不一样的。它是什么不重要,也无意义,重要的是你怎么观察它,谁观察它的,怎么解释它。

1.2. 使用相机去解释M,N,P

矩阵P是模型视图矩阵,P又可以拆分出两个矩阵,一个是模型矩阵Model,一个是视图矩阵View, 模型矩阵只作用某一个模型上,而View矩阵是作用到所有的模型上,View又可以拆分出平移矩阵T,和旋转矩阵R,(一般来说不能拆分出缩放矩阵)因此R矩阵就可以理解为视点坐标系,R矩阵的三个列向量就是视点坐标系的X轴,Y轴,Z轴,T矩阵是一个向量,也是视点坐标系的原点,也可以理解为相机的位置,由于对P矩阵有不同的拆分方法,每种拆分方法可以拆分出不同的TR,所以相机的位置和放置的方向可以有很多种方法。 如下图:

 技术分享

 

 

  投影矩阵N本来的作用就是把模型变换到一个边长为2的立方体内,方便剪裁,可以把投影矩阵解释为八个顶点形成的棱柱体,这个棱柱可以是正棱柱或者斜棱柱,这个棱柱的八个顶点为参数可以合成一个矩阵,这个矩阵就是N,这个棱柱体的八个顶点的坐标乘以N后,就为变成边长为2的立方体的顶点。如下图:

 技术分享

1.3. 使用坐标变换去解释M,N,P

除了M, N解释为相机外, M* N * P * A = A1又可以理解为 M * N * T * R * Model * A = A1, (T, R, Model的含义上面已经讲过),  还可以从坐标变换的角度去理解,每乘以一个矩阵就相当于进行了一次坐标变换,ModelR, T, N, M, 就相当于进行了一系列变换后生成了新的坐标,这个左边的Z轴最终变成了01之间,也就是opengl中深度坐标的范围。最终按照变换后的坐标,使用绘制点的函数绘制到屏幕上。

2. 多相机的使用

既然知道了 M* N * P * A = A1, 也就是一个点变换到屏幕上的过程,并且相机就是指的N, N, 这两个矩阵,那么在什么情况下会用到多相机呢?就是绘制多个模型,但是这几个模型的M,N值不一样的时候,比如说你绘制了一个球,再绘制了一个公告板(就是一个模型的永远朝向相机),在这种情况下,就需要两个相机,一个相机绘制球,一个相机绘制公告板。或者说,你在绘制模型的同时,还想在屏幕的左下角绘制一个坐标系,这个坐标系只能旋转,不能平移缩放,只起个指示模型的方向的作用,在这种情况下,可以单独使用一个相机绘制这个坐标系,其它的模型要使用另一个相机。

3. THREE.JS使用多相机绘制坐标系

THREE.JS中实现左下角一个坐标轴,只旋转,不平移不缩放,仅仅起指示作用。如下图:

 技术分享

 

 

代码如下:

//立即执行函数,绘制坐标轴

//绘制Y

(function (){

 var sourcePos = new THREE.Vector3(0, 0, 0);

var targetPos = new THREE.Vector3(0, 100, 0);

var direction = new THREE.Vector3().sub(targetPos, sourcePos);

var arrow = new THREE.ArrowHelper(direction.clone().normalize(), sourcePos, direction.length(), 0xff0000, 15, 15);

AxisScene.add(arrow);

      })();

 

//绘制X

(function (){

var sourcePos = new THREE.Vector3(0, 0, 0);

var targetPos = new THREE.Vector3(100, 0, 0);

var direction = new THREE.Vector3().sub(targetPos, sourcePos);

var arrow = new THREE.ArrowHelper(direction.clone().normalize(), sourcePos, direction.length(), 0x00ff00, 15, 15);

 AxisScene.add(arrow);

           })();

 

//绘制Z

 (function (){

var sourcePos = new THREE.Vector3(0, 0, 0);

var targetPos = new THREE.Vector3(0, 0, 100);

var direction = new THREE.Vector3().sub(targetPos, sourcePos);

var arrow = new THREE.ArrowHelper(direction.clone().normalize(), sourcePos, direction.length(), 0x0000ff, 15, 15);

AxisScene.add(arrow);

            })();

 

//专门为绘制坐标轴设置一个相机

 AxisCamera = new THREE.Plot3DCamera(-100, 100, 100, -100, -500, 500);

 renderer.setViewport(0, 0, window.innerWidth, window.innerHeight);

 

//scene, camera原来的场景节点和相机,绘制场景

renderer.render(scene, camera);

renderer.autoClearColor = false;

 

//坐标系绘制到左下角

renderer.setViewport(window.innerWidth - 100, window.innerHeight - 100, 100, 100);

//绘制坐标系

renderer.render(CADscene, CADcamera);

 

交流图形学的一切,尤其是大型程序的设计,每天有原创文章
微信公众号: GraphicsPlatform

qq群: 559684273
qq:   1829634717

将近两百篇图形学相关的技术文章,经常更新
技术博客: http://www.cnblogs.com/lizhengjin

网站及案例 www.webglchina.cn

对相机的理解及使用多相机绘制只旋转的坐标系

标签:

原文地址:http://www.cnblogs.com/lizhengjin/p/5923598.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!