三维模型视图投影矩阵变化矩阵意义?什么是三维图形复合变换

 上传我的文档
 下载
 收藏
该文档贡献者很忙,什么也没留下。
 下载此文档
三维投影变换的MATLAB实现
下载积分:590
内容提示:三维投影变换的MATLAB实现
文档格式:PDF|
浏览次数:123|
上传日期: 14:13:01|
文档星级:
全文阅读已结束,如果下载本文需要使用
 590 积分
下载此文档
该用户还上传了这些文档
三维投影变换的MATLAB实现
关注微信公众号向量、矩阵、三维变换及四元数 - 知乎专栏
{"debug":false,"apiRoot":"","paySDK":"/api/js","wechatConfigAPI":"/api/wechat/jssdkconfig","name":"production","instance":"column","tokens":{"X-XSRF-TOKEN":null,"X-UDID":null,"Authorization":"oauth c3cef7c66aa9e6a1e3160e20"}}
{"database":{"Post":{"":{"contributes":[{"sourceColumn":{"lastUpdated":,"description":"","permission":"COLUMN_PUBLIC","memberId":1491332,"contributePermission":"COLUMN_PUBLIC","translatedCommentPermission":"all","canManage":true,"intro":"","urlToken":"HiCuteTom","id":24251,"imagePath":"4b70deef7","slug":"HiCuteTom","applyReason":"0","name":"TOM的游戏开发札记","title":"TOM的游戏开发札记","url":"/HiCuteTom","commentPermission":"COLUMN_ALL_CAN_COMMENT","canPost":true,"created":,"state":"COLUMN_NORMAL","followers":474,"avatar":{"id":"4b70deef7","template":"/{id}_{size}.jpg"},"activateAuthorRequested":false,"following":false,"imageUrl":"/4b70deef7_l.jpg","articlesCount":17},"state":"accepted","targetPost":{"titleImage":"/v2-4daebcb4828340cdf3efe7_r.jpg","lastUpdated":,"imagePath":"v2-4daebcb4828340cdf3efe7.jpg","permission":"ARTICLE_PUBLIC","topics":[,6199],"summary":"数学概念,特别是矩阵变换相关的数学知识一直是困扰图形学初学者的一大难关。即使看了大量的相关资料,看起代码或动手写代码的时候,还是感到力不从心。当遇到world/view/proj等矩阵的典型应用场景的时候,尚且还能简单调用几个API完成任务。但是一遇到稍微…","copyPermission":"ARTICLE_COPYABLE","translatedCommentPermission":"all","likes":0,"origAuthorId":0,"publishedTime":"T17:18:16+08:00","sourceUrl":"","urlToken":,"id":1216636,"withContent":false,"slug":,"bigTitleImage":false,"title":"向量、矩阵、三维变换及四元数","url":"/p/","commentPermission":"ARTICLE_ALL_CAN_COMMENT","snapshotUrl":"","created":,"comments":0,"columnId":0,"content":"","parentId":0,"state":"ARTICLE_PUBLISHED","imageUrl":"/v2-4daebcb4828340cdf3efe7_r.jpg","author":{"bio":"时常用心,偶有所得","isFollowing":false,"hash":"a0a1ea8dbd9dcb1cb253","uid":28,"isOrg":false,"slug":"HiCuteTom","isFollowed":false,"description":"多年端游研发经历,游戏架构,图形引擎优化","name":"HiTom","profileUrl":"/people/HiCuteTom","avatar":{"id":"v2-8d53afdb17bc9776905f","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},"memberId":1491332,"excerptTitle":"","voteType":"ARTICLE_VOTE_CLEAR"},"id":495151}],"title":"向量、矩阵、三维变换及四元数","author":"HiCuteTom","content":"数学概念,特别是矩阵变换相关的数学知识一直是困扰图形学初学者的一大难关。即使看了大量的相关资料,看起代码或动手写代码的时候,还是感到力不从心。当遇到world/view/proj等矩阵的典型应用场景的时候,尚且还能简单调用几个API完成任务。但是一遇到稍微复杂一点的场景,就感觉对相关数学概念理解太过浅陋。本文尝试深入剖析一番矩阵变换和投影,偏重理解思路,讲求实用技巧。细细体会可加深对三维变换的理解。当然本文都是我自己学习相关数学知识过程中的一些心得,理解不对的,还请指出。本文采用D3D左手坐标系,向量采用行向量,透视投影深度范围为。1. 向量与点向量无所谓位置,可以表示为;点用行向量表示为,称为齐次坐标经常还用到非齐次坐标,其表示的点是向量和点的区别在于,点可以平移,而向量无所谓平移。向量可以理解为原点向空间一点的矢量,即 2. 线性插值二维直线上取两点,该直线上任何一点满足:3. 基本变换常用的基本变换包括平移、旋转、伸缩等。理解基本变换应该从基变换出发。所谓基变换,就是变换矩阵对单位矩阵基向量的作用方式。对于任意向量,都可以写成,而向量与矩阵的乘积可表示为即:转换矩阵的每一行都能解释成将原基向量经矩阵转换后的新基向量。例如:平移可以表示如下:伸缩可以表示如下:注意观察变换矩阵相应分量对平移和伸缩变换的作用。变换矩阵最后一行行向量的作用是分别对原基向量做平移;变换矩阵对角元素的作用是对原基向量做伸缩。从模型坐标转换为世界坐标的世界矩阵表示如下:观察该矩阵发现,行向量分别是各模型坐标基向量变换到世界坐标后的单位向量,而是模型原点对世界坐标系原点的偏移。对于绕轴的旋转来说,可以把向量分解为两个分量,只有垂直分量对旋转结果有贡献。另一个理解方式是把旋转分解为分别对轴的旋转,旋转矩阵就是这三个矩阵的积。下面再看视图矩阵的构造。给定的三个D3DXVECTOR3向量,调用D3DXMatrixLookAtLH()可得到为[1]:: 世界坐标系中相机坐标系的基: 世界坐标系中相机坐标系的基: 世界坐标系中相机坐标系的基: 世界坐标系中,原点指向的向量向基的投影,即旧原点向新原点的平移对于镜头来说,局部坐标系(或模型坐标系)和视图坐标系是同一个坐标系。世界矩阵将局部坐标转换为世界坐标,同时也把视图坐标转换为世界坐标[9]。所以该视图矩阵和世界矩阵互为逆矩阵。容易验证(其中为单位矩阵)另外,我们发现上述计算的各基向量分别处于列向量的位置上,这里不能把向量直接理解成对原基向量的变换。这是因为,从世界坐标向视图坐标转换时,转换后的点相对于转换前的点,在世界坐标中的位置并没有改变,只是观察基坐标发生了变化。此时应该将变换理解为世界坐标上一点向视图坐标上的投影,也就是该点对新坐标轴向量的投影。投影后的坐标为:4. 投影变换投影变换是将视图坐标变换到一个立方体空间的过程。有两种投影方式,透视投影和平行投影。平行投影的对象原先也在一个立方体中,所以投影过程就是一个线性的伸缩和平移变换。透视投影的对象则在一个棱台内[7],所以投影过程带有坐标轴的扭曲。投影后的立方体可简单表示为六个面(左右,上下,远近):平行投影伸缩系数为,平移表示为。注意到,也经过了伸缩变换。若仅进行伸缩变换,实际是变换到原点为三个面的交点,立方体为的范围内。最终正交变换矩阵为透视投影伸缩系数为,坐标对分量都有作用。转换后的坐标对是线性关系。透视投影变换矩阵为注意上述都是情况下的一般情况,若变换到原点,可以令下面介绍,给定透视投影矩阵,如何得到viewfrustum各平面在view空间的表示方法[2]。而投影后的立方体各面可表示为,由此可得到viewfrustum各平面在view空间可表示为对于TBDR[3]中使用的平面方程也可由此得到,只是需使用offcenter情况下的一般矩阵。有篇文章[4]从平面法线的角度也得到了同样的结果。另外需要提到的是,此节所讲的投影是投影到立方体,并没有丢失维度信息,所以和平移、旋转和缩放一样,都是可逆的。5. 四元数与对偶四元数单位四元数可用于旋转。该单位四元数可以表示为他对应一个以单位向量为轴旋转角度的旋转操作。例如,对一个点,定义纯四元数,经四元数旋转操作后也是一个纯四元数,其中就是点绕轴旋转角度后得到的。之所以使用纯四元数,是因为纯四元数代表了三维空间的一个点,而纯四元数经过上述旋转操作后得到的还是一个纯四元数,即还是一个三维空间中的点。四元数和对偶四元数主要用于沿着旋转路径插值。关于四元数的理解,可以看这篇文章[5]。对偶四元数,可参考[6][10]。6. 参考文献:[1] [2] [3] [4] [5] [6] [7] [8] [9] [10] 注:转载请注明出处。","updated":"T09:18:16.000Z","canComment":false,"commentPermission":"anyone","commentCount":1,"collapsedCount":0,"likeCount":2,"state":"published","isLiked":false,"slug":"","lastestTipjarors":[],"isTitleImageFullScreen":false,"rating":"none","titleImage":"/v2-4daebcb4828340cdf3efe7_r.jpg","links":{"comments":"/api/posts//comments"},"reviewers":[],"topics":[{"url":"/topic/","id":"","name":"计算机图形学"},{"url":"/topic/","id":"","name":"游戏开发"},{"url":"/topic/","id":"","name":"Unity(游戏引擎)"}],"adminClosedComment":false,"titleImageSize":{"width":550,"height":363},"href":"/api/posts/","excerptTitle":"","tipjarState":"activated","tipjarTagLine":"真诚赞赏,手留余香","sourceUrl":"","pageCommentsCount":1,"tipjarorCount":0,"annotationAction":[],"hasPublishingDraft":false,"snapshotUrl":"","publishedTime":"T17:18:16+08:00","url":"/p/","lastestLikers":[{"bio":"程序猿","isFollowing":false,"hash":"ddb8f95bffb","uid":307800,"isOrg":false,"slug":"leaos","isFollowed":false,"description":"","name":"shaoleaos","profileUrl":"/people/leaos","avatar":{"id":"v2-784107bee798d24f89d545","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},{"bio":"无","isFollowing":false,"hash":"c6dde99c9ed992cc1a099e959938fada","uid":36,"isOrg":false,"slug":"call-draw","isFollowed":false,"description":"","name":"call draw","profileUrl":"/people/call-draw","avatar":{"id":"da8e974dc","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false}],"summary":"数学概念,特别是矩阵变换相关的数学知识一直是困扰图形学初学者的一大难关。即使看了大量的相关资料,看起代码或动手写代码的时候,还是感到力不从心。当遇到world/view/proj等矩阵的典型应用场景的时候,尚且还能简单调用几个API完成任务。但是一遇到稍微…","reviewingCommentsCount":0,"meta":{"previous":null,"next":null},"annotationDetail":null,"commentsCount":1,"likesCount":2,"FULLINFO":true}},"User":{"HiCuteTom":{"isFollowed":false,"name":"HiTom","headline":"多年端游研发经历,游戏架构,图形引擎优化","avatarUrl":"/v2-8d53afdb17bc9776905f_s.jpg","isFollowing":false,"type":"people","slug":"HiCuteTom","bio":"时常用心,偶有所得","hash":"a0a1ea8dbd9dcb1cb253","uid":28,"isOrg":false,"description":"多年端游研发经历,游戏架构,图形引擎优化","profileUrl":"/people/HiCuteTom","avatar":{"id":"v2-8d53afdb17bc9776905f","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false,"badge":{"identity":null,"bestAnswerer":null}}},"Comment":{},"favlists":{}},"me":{},"global":{"experimentFeatures":{"ge3":"ge3_9","ge2":"ge2_1","nwebStickySidebar":"sticky","newMore":"new","liveReviewBuyBar":"live_review_buy_bar_2","liveStore":"ls_a2_b2_c1_f2","isOffice":"false","homeUi2":"default","answerRelatedReadings":"qa_recommend_with_ads_and_article","remixOneKeyPlayButton":"headerButton","qrcodeLogin":"qrcode","newBuyBar":"livenewbuy3","newMobileColumnAppheader":"new_header","zcmLighting":"zcm","favAct":"default","appStoreRateDialog":"close","mobileQaPageProxyHeifetz":"m_qa_page_nweb","iOSNewestVersion":"4.2.0","default":"None","wechatShareModal":"wechat_share_modal_show","qaStickySidebar":"sticky_sidebar","androidProfilePanel":"panel_b"}},"columns":{"next":{}},"columnPosts":{},"columnSettings":{"colomnAuthor":[],"uploadAvatarDetails":"","contributeRequests":[],"contributeRequestsTotalCount":0,"inviteAuthor":""},"postComments":{},"postReviewComments":{"comments":[],"newComments":[],"hasMore":true},"favlistsByUser":{},"favlistRelations":{},"promotions":{},"switches":{"couldAddVideo":false},"draft":{"titleImage":"","titleImageSize":{},"isTitleImageFullScreen":false,"canTitleImageFullScreen":false,"title":"","titleImageUploading":false,"error":"","content":"","draftLoading":false,"globalLoading":false,"pendingVideo":{"resource":null,"error":null}},"drafts":{"draftsList":[],"next":{}},"config":{"userNotBindPhoneTipString":{}},"recommendPosts":{"articleRecommendations":[],"columnRecommendations":[]},"env":{"edition":{},"isAppView":false,"appViewConfig":{"content_padding_top":128,"content_padding_bottom":56,"content_padding_left":16,"content_padding_right":16,"title_font_size":22,"body_font_size":16,"is_dark_theme":false,"can_auto_load_image":true,"app_info":"OS=iOS"},"isApp":false},"sys":{},"message":{"newCount":0},"pushNotification":{"newCount":0}}矩阵-DirectX与OpenGL的不同 - zdd - 博客园
随笔 - 202, 文章 - 65, 评论 - 1715, 引用 - 0
矩阵是三维图形学中不可或缺的部分,几乎所有和变换相关的操作都涉及矩阵,世界变换,视图变换,投影变换,视口变换无一不需要矩阵,但是当今的两大主流图形库DirectX和OpenGL对矩阵操作却有着细微的差别,大多数的图形学书籍都以OpenGL为基础进行阐述,游戏编程类的书籍则更多使用DirectX,这就难免产生混淆,今天这篇主要讲讲两者在操作矩阵的时候有何不同。
在三维图形学中,一般使用四维矩阵,也就是四行四列的方阵,下面是一个典型的四维矩阵
既然是三维图形学,为什么使用四维矩阵呢?主要有两个原因,第一,为了平移变换,第二,为了区别点和向量。
行向量与列向量
对于一个四维向量,它是行向量还是列向量呢?DirectX使用行向量,如下。
而OpenGL则使用列向量,如下
矩阵与向量相乘
顶点进行几何变换的过程,从数学层面讲,就是顶点和矩阵相乘产生新顶点的过程,那么向量与矩阵相乘时顺序是怎样的呢?这取决于该向量是行向量还是列向量,我们知道两个矩阵Aij和Bxy若能相乘,则必须满足j=x才行,也就是说左边矩阵的列数要等于右边矩阵的行数,由于行向量和列向量本质上也是矩阵,也满足矩阵乘法的规律。
在DirectX中,使用行向量,所以向量和矩阵相乘的时候,向量在左,矩阵在右,如下。
而OpenGL中则使用列向量,相乘的时候矩阵在左,向量在右,如下。注意矩阵乘法中,若用^表示转置,则(AB)^=B^A^,所以下面的矩阵与DirectX中的矩阵互为转置矩阵,感谢网友指点。
比如对于平移变换来说,如果使用DirectX,那么m41,m42,m43分别对应三个平移分量,对应下面的Tx,Ty和Tz。
如果使用OpenGL,那么m11,m21,m31分别对应三个平移分量。
可以看出,对于同一个变换,DirectX中的矩阵和OpenGL中的矩阵互为转置矩阵。
如果有多个变换作用于一个顶点,那么可以先将所有的变换矩阵相乘,得到一个变换矩阵,最后将这个变换矩阵应用到顶点即可,这就涉及到矩阵的连乘,这时候如何安排矩阵的先后顺序呢?假设现在有三个变换,分别是平移变换,对应矩阵T,旋转变换,对应矩阵R,缩放变换,对应矩阵S,顺序是先平移,再旋转,后缩放,那么这个矩阵乘法该如何去写呢?
在DirectX中,矩阵乘法的顺序是从左到右,变换生效的先后顺序也是从左到右
而在OpenGL中,矩阵连乘的顺序是从右到左
不管是哪种方式,都是先产生作用的矩阵离顶点近(上面的T),后产生作用的矩阵离顶点远(上面的S)。
一个误区,左手系与右手系
矩阵乘法的顺序与坐标系是左手系还是右手系有关系么?根本没啥关系!
常用变换矩阵
下面给出几种常用的变换在DirectX和OpenGL中对应的矩阵,下图中左面是DirectX中的矩阵,右面是OpenGL中的矩阵。
&&&&&&&&&&
&&&&&&&&&&
&&&&&&&&&&
&&&&&&&&&&
缩放变换矩阵,两者是一致的,因为缩放变换的变换因子都在矩阵的对角线上,所以转置矩阵等于其自身。}

我要回帖

更多关于 视图矩阵 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信