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. RPC 笔记(01)— RPC概念、调用流程、RPC 与 Restful API 区别

    1. 基本概念 PRC 远程过程调用 Remote Procedure Call,其就是一个节点请求另外一个节点提供的服务.当两个物理分离的子系统需要建立逻辑上的关联时,RPC 是牵线搭桥的常见技术手 ...

  2. C++ 笔记(28)— C++ 中 NULL和 nullptr 的区别

    最近看公司代码的时候发现在判断指针是否为空的时候,有的时候用的是 NULL, 有的时候用的是 nullptr 感觉很奇怪,好奇心驱使我查了下两者的区别,发现还是有很多细节需要学习的. 1. NULL ...

  3. gcc 和 g++ 的联系和区别,使用 gcc 编译 c++

    GCC 编译器已经为我们提供了调用它的接口,对于 C 语言或者 C++ 程序,可以通过执行 gcc 或者 g++ 指令来调用 GCC 编译器. 实际使用中我们更习惯使用 gcc 指令编译 C 语言程序 ...

  4. Python2 与 Python3 区别

    Python2.x 与 Python3.x 区别 1. print 函数 Python2 中 print 是语句(statement),Python3 中 print 则变成了函数.在 Python3 ...

  5. Docker 入门系列(1)- 初识容器,镜像、容器、仓库的区别

    Docker 简介 Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从Apache2.0协议开源. Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级.可移植的容器中,然后发 ...

  6. HTTP 协议入门 — (TCP/IP协议族、通信传输流、URI 与 URL 的区别、Cookie 状态管理、HTTP 支持的方法、状态码类别、HTTP 首部字段)

    TCP/IP协议族 在介绍 HTTP 协议之前,我们先对 TCP/IP 协议族有个大概的了解,TCP/IP 协议从上到下主要分为应用层.传输层.网络层和数据链路层,各层的主要功能如下表所示: 协议层 ...

  7. python二进制打开(rb)和文本格式打开(r)什么区别?

    使用 open() 函数以文本格式打开文件和以二进制格式打开文件,唯一的区别是对文件中换行符的处理不同. 在 Windows 系统中,文件中用 "\r\n" 作为行末标识符(即换行 ...

  8. python中__dict__与dir()区别

    前言 Python下一切皆对象,每个对象都有多个属性(attribute),Python对属性有一套统一的管理方案. __dict__与dir()的区别: dir()是一个函数,返回的是list: _ ...

  9. java和C#面向对象的区别

    问题:C#中的构造函数和java的构造函数一样吗? 答: .net的项目中,写实体Entity属性时,经常会为每一个属性写一对get和set方法,在用到这个实体或是一个类时,通过new实例化一个对象, ...

最新文章

  1. 一些很实用且必用的小脚本代码:
  2. SQLServer数据库如何收缩日志空间?
  3. 中国SaaS死或生之四:卧榻之侧,是谁在捅刀 SaaS?
  4. mybatis plus 链式编程查询
  5. 智能小程序档案馆——如何给“包”瘦身
  6. c++用一级运算比较大小_16.初中数学:怎么比较a、b、c、d的大小?幂的运算,基础常见考题...
  7. 【Elasticsearch】Elasticsearch bouncing result 问题
  8. jquery利用appendTo动态创建元素
  9. tensor.detach() 和 tensor.data 的区别
  10. jQuery基础之事件
  11. STM32F407 FSMC驱动NAND FLASH MX30LF2GE8AB 附带测试程序链接
  12. JS编程:查找数组元素位置
  13. 安卓音频输出采样率_安卓里LDAC的采样率问题
  14. 【小白学Java】D14》》》ArrayList应用<两大案例的数据分组聚合>
  15. 深圳海伊视讯布控球成功对接海康萤石云平台安装调式
  16. 在钉钉小程序中实现录音和播放功能实例
  17. 如何批量修改文件夹中不同文件的名字?命令不正确~
  18. <Zhuuu_ZZ>大数据技术之Flume详解
  19. 视频教程-三维游戏引擎开发-图形理论基础-其他
  20. Linux学习入门-------------------------VMvare与镜像的安装与配置

热门文章

  1. 删除数据库中与同步数据冗余的数据(多对多)
  2. Java程序员总结分布式架构,你又了解多少呢?
  3. 开发工具总结(4)之Android Studio3.0填坑指南
  4. ThumbProcess.exe错误的解决方法
  5. Play框架拾遗之五:其他知识点
  6. phalcon遇到的那些坑
  7. 天命剑之天命的含义--天行有悖,乃命羲和。
  8. 我的jquery之路
  9. Socket2实现tcp端口扫描
  10. 主宰全球的10大算法