DirectX中有两个很相似的函数,输入与输出的参数格式完全一样,都是输入一个三维向量(D3DXVECTOR3)和一个矩阵(D3DXMATRIX),输出变换之后的向量(D3DXVECTOR3)。

函数内部的工作机制也很类似,都是把三维向量扩充成四维向量,然后和矩阵相乘,得到变换之后的四维向量,再把四维向量转换成三维向量输出。

两者的区别在于开始把三维向量转换成四维向量时,第四维分量的取值。D3DXVec3TransformNormal( ) 用于矢量的变换,第四维分量为0。D3DXVec3TransformCoord( )  用于坐标的变换,第四维分量为1。

为什么要有这样的区别呢?

在三维坐标系中,虽然矢量和坐标都用(x,y,z)表示,但是坐标仅表示点在坐标系中的位置,没有方向和长度。三维变换中,坐标点可以平移。由于我们使用向量与矩阵的乘法来计算三维变换,而变换矩阵是4x4的矩阵,只能和四维行向量相乘,因此需要扩充第四维分量来实现三维变换的乘法计算,把第四维分量设置成1,可以保证平移变换的实现。

矢量表示的是一段有方向和长度的有向线段,两个坐标点之间的矢量可以用终点坐标减起点坐标来计算。在三维的表示方法中,两个三维向量相减,结果还是三维向量,即(Ax,Ay,Az)-(Bx,By,Bz)=(X,Y,Z)。如果扩充到四维表示,把坐标点的第四维分量设置成1,那么用减法计算矢量时,得到的四维向量的前三维分量和三维计算一致,但第四维等于0,即(Ax,Ay,Az,1)-(Bx,By,Bz,1)=(X,Y,Z,0)。矢量(x,y,z)一般表示成从原点(0,0,0)到坐标点(x,y,z)的有向线段,但是它可以任意的坐标点作为起点或终点,只要方向和长度保持一致。因此矢量没有特定的位置。四维表示时,由于第四维等于0,因此,矢量也就不可以实现平移变换。当然,没有位置本来也就不需要平移了。

所以,通过第四维的0,忽略平移变换,是矢量变换与坐标变换的根本区别。

但是矢量变换与坐标变换还是有关系的。可以验证一下,在对矢量进行三维变换时,可以先假设一个矢量的起点为原点(0,0,0),终点是(x,y,z),变换时先使用D3DXVec3TransformCoord( ) 变换起点,再使用D3DXVec3TransformCoord( ) 变换终点,然后再把变换后的终点与起点相减得到转换后的矢量值,这个减法一方面是计算矢量的值,另一方面也相当于忽略了平移变换,因为原点只会发生平移变换。因此,矢量变换的结果与原矢量终点坐标(x,y,z)变换之后的值是完全不一样的。

该结果与直接使用D3DXVec3TransformNormal( )一致。

代码片断:

D3DXVECTOR3 O(0,0,0);    //原点坐标
D3DXVECTOR3 S(x,y,z);    //矢量坐标
D3DXMATRIX M;

/**//* 设置变换矩阵M */

//变换矢量终点坐标
D3DXVec3TransformCoord(&S,&S,&M);    
//变换矢量起点坐标
D3DXVec3TransformCoord(&O,&O,&M);
//计算变换后的矢量
S=S-O;

转:D3DXVec3TransformNormal() 与 3DXVec3TransformCoord() 的区别的更多相关文章

  1. 【转载】D3DXVec3TransformNormal and D3DXVec3TransformCoord

    原文:D3DXVec3TransformNormal and D3DXVec3TransformCoord D3DXVec3TransformCoord 对向量进行变换,没啥好说明的,默认向量为行向量 ...

  2. c#与java的区别

    经常有人问这种问题,用了些时间java之后,发现这俩玩意除了一小部分壳子长的还有能稍微凑合上,基本上没什么相似之处,可以说也就是马甲层面上的相似吧,还是比较短的马甲... 一般C#多用于业务系统的开发 ...

  3. jquery和Js的区别和基础操作

    jqery的语法和js的语法一样,算是把js升级了一下,这两种语法可以一起使用,只不过是用jqery更加方便 一个页面想要使用jqery的话,先要引入一下jqery包,jqery包从网上下一个就可以, ...

  4. 【原】nodejs全局安装和本地安装的区别

    来微信支付有2年多了,从2年前的互联网模式转变为O2O模式,主要的场景是跟线下的商户去打交道,不像以往的互联网模式,有产品经理提需求,我们帮忙去解决问题. 转型后是这样的,团队成员更多需要去寻找业务的 ...

  5. 探究@property申明对象属性时copy与strong的区别

    一.问题来源 一直没有搞清楚NSString.NSArray.NSDictionary--属性描述关键字copy和strong的区别,看别人的项目中属性定义有的用copy,有的用strong.自己在开 ...

  6. X86和X86_64和X64有什么区别?

    x86是指intel的开发的一种32位指令集,从386开始时代开始的,一直沿用至今,是一种cisc指令集,所有intel早期的cpu,amd早期的cpu都支持这种指令集,ntel官方文档里面称为&qu ...

  7. Java中Comparable与Comparator的区别

    相同 Comparable和Comparator都是用来实现对象的比较.排序 要想对象比较.排序,都需要实现Comparable或Comparator接口 Comparable和Comparator都 ...

  8. MySQL中interactive_timeout和wait_timeout的区别

    在用mysql客户端对数据库进行操作时,打开终端窗口,如果一段时间没有操作,再次操作时,常常会报如下错误: ERROR (HY000): Lost connection to MySQL server ...

  9. 设置line-height:1.5和line-height:150%或者line-height:150px的区别

    直接正题: 看一下line-height可能的值: 其实可以分为两类: (1)不带单位的(如line-height:1.5),这种是推荐使用的: (2)带单位的(如line-heigth:30px/1 ...

随机推荐

  1. Verilog 加法器和减法器(3)

    手工加法运算时候,我们都是从最低位的数字开始,逐位相加,直到最高位.如果第i位产生进位,就把该位作为第i+1位输入.同样的,在逻辑电路中,我们可以把一位全加器串联起来,实现多位加法,比如下面的四位加法 ...

  2. 基于fasttext的情感分析,准备先做一版

    博客文章地址: https://blog.csdn.net/sinat_33741547/article/details/78803766 代码地址: https://github.com/lpty/ ...

  3. 解析eml文件

    之前使用lumisoft解析eml,总是会出现很奇怪的问题,所以改使用微软自家的com库,确实厉害兼容性更好,代码 string file = emailPath; CDO.Message oMsg ...

  4. 用非递归、不用栈的方法,实现原位(in-place)的快速排序

    大体思路是修改Partition方法将原本枢数的调整放到方法结束后去做.这样因为数组右侧第一个大于当前枢数的位置就应该是未划分的子数组的边界.然后继续进行Partition调整.这种写法照比递归的写法 ...

  5. caffe添加python数据层

    caffe添加python数据层(ImageData) 在caffe中添加自定义层时,必须要实现这四个函数,在C++中是(LayerSetUp,Reshape,Forward_cpu,Backward ...

  6. iOS开发-仿大众点评iPad侧边导航栏

    昨天其实已经写了一篇侧边栏的文章,不过感觉还不是很清晰,这篇文章算是补充吧,iPad上看了大众点评的侧边栏,基本上百分之九十类似,具体效果可参考下图: 对比昨天主要做了两个修改,一个是图片和文字的显示 ...

  7. layer.tips定义弹出的宽度

    layer.tips('xxx', '.onlinetest', { tips: [1, '#3595CC'], area: ['500px', 'auto'], time: 4000 });

  8. 【google面试题】求1到n的正数中1出现的次数的两种思路及其复杂度分析

    问题描写叙述: 输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数.比如输入12,从1到12这些整数中包括1 的数字有1.10.11和12.1一共出现了5次. 这是一道广为流传的googl ...

  9. 【R】函数-数学函数

  10. C#遍历可变化的集合

    如果用foreach,会造成被遍历的集合更改后带来异常问题. 方法一:用for循环可有效的解决这个问题. ;i<List.Count;i++) { if(条件是真) { List.Remove( ...