本文参考dx11龙书 Chapter1 vector algebra(向量代数)

要想学好游戏编程,扎实的数学知识是尤为重要的,下面将对dx11龙书中有关向量的数学知识做一下总结。

在数学中,几何向量(也称为欧几里得向量,通常简称向量、矢量),指具有大小(magnitude)和方向(direction)的几何对象,可以形象化地表示为带箭头的线段,箭头所指:代表向量的方向、线段长度:代表向量的大小。

向量的表示方式一般有3种:

  1.代数表示:一般印刷用黑体小写字母α、β、γ…或a、b、c… 等来表示,手写用在a、b、c…等字母上加一箭头表示

  2.几何表示:用有向线段表示

  3.坐标表示

(注:directx使用的是左手系,下面不作说明均以左手系为准)

向量的一些基本操作(部分摘自百度百科)

1.向量的模,即向量的长度。

向量a的模记作|a|。向量的模是非负实数,是可以比较大小的。因为方向不能比较大小,所以向量也就不能比较大小。对于向量来说“大于”和“小于”的概念是没有意义的。例如,“向量AB>向量CD”是没有意义的。

2.单位向量
长度为一个单位(即模为1)的向量,叫做单位向。与向量a同向,且长度为单位1的向量,叫做a方向上的单位向量,记作a0,a0=a/|a|。
3.向量的加减法
向量的加法满足平行四边形法则和三角形法则。OB+OA=OC。
a+0=0+a=a。
向量加法的运算律:
交换律:a+b=b+a;
结合律:(a+b)+c=a+(b+c)。
减法与加法类似
4.数量积(点积)
定义:已知两个非零向量a,b。作OA=a,OB=b,则角AOB称作向量a和向量b的夹角,记作〈a,b〉并规定0≤〈a,b〉≤π
定义:两个向量的数量积(内积、点积)是一个数量(没有方向),记作a·b。若a、b不共线,则a·b=|a|·|b|·cos〈a,b〉(依定义有:cos〈a,b〉=a·b / |a|·|b|);若a、b共线,则a·b=±∣a∣∣b∣。
向量的数量积的坐标表示:a·b=x·x'+y·y'。
向量的数量积的运算律
a·b=b·a(交换律)
(λa)·b=λ(a·b)(关于数乘法的结合律)
(a+b)·c=a·c+b·c(分配律)
向量的数量积的性质
a·a=|a|的平方。
a⊥b〈=〉a·b=0。
|a·b|≤|a|·|b|。
5.向量积(叉积)
定义:两个向量a和b的向量积
(外积、叉积)是一个向量,记作a×b(这里“×”并不是乘号,只是一种表示方法,与“·”不同,也可记做“∧”)。若a、b不共线,则a×b的模是:∣a×b∣=|a|·|b|·sin〈a,b〉;a×b的方向是:垂直于a和b,且a、b和a×b按这个次序构成右手系。若a、b垂直,则∣a×b∣=|a|*|b|(此处与数量积不同,请注意),若a×b=0,则a、b平行。向量积即两个不共线非零向量所在平面的一组法向量。
运算法则:运用三阶行列式
设a,b,c分别为沿x,y,z轴的单位向量
A=(x1,y1,z1)B=(x2,y2,z2)则A*B=
a b c
x1 y1 z1
x2 y2 z2
向量的向量积性质:
∣a×b∣是以a和b为边的平行四边形面积。
a×a=0。
a平行b〈=〉a×b=0
向量的向量积运算律
a×b=-b×a
(λa)×b=λ(a×b)=a×(λb)
a×(b+c)=a×b+a×c.
(a+b)×c=a×c+b×c.
6.向量投影

给定一个向量u和v,求u在v上的投影向量,如下图。

假设u在v上的投影向量是u’,且向量u和v的夹角为theta。一个向量有两个属性,大小和方向,我们先确定u’的大小(即长度,或者模),从u的末端做v的垂线,那么d就是u’的长度。而u’和v的方向是相同的,v的方向v/|v|也就是u’的方向。所以有

                          (1)

再求d的长度。

                      (2)

最后求cos(theta)

                   (3)

联合求解方程(1)(2)(3)得到

这就是最终的投影向量。

而这个向量的长度d是

============================

以下是旧的推导,也保留。

XNA MathVectors

下面介绍一些xna math库中常用的向量结构及方法

1.向量类型

有XMVECTOR,XMFLOAT2,XMFLOAT3,XMFLOAT4等几种类型,具体可以看dx11龙书1.6.1节

在这一章中作者给出使用向量类型应注意的5点:

(1)、 对局部变量和全局变量,使用XMVECTOR类型;

(2)、 对类的数据成员,使用XMFLOAT2, XMFLOAT3和XMFLOAT4数据成员;

(3)、 在进行计算之前,使用载入函数(loading functions)来将XMFLOAT*类型转换成XMVECTOR类型;

(4)、 用XMVECTOR的实例进行计算;

(5)、 使用存储函数(storage functions)来将XMVECTOR转换成XMFLOAT*类型

2.Loading and Storage Methods(载入和存储函数)

我们用下面的方法来加载数据,从XMFLOAT*到XMVECTOR

XMVECTOR XMLoadFloat3(CONST XMFLOAT3 *pSource);

XMVECTOR XMLoadInt3(CONST UINT* pSource);

XMVECTOR XMLoadColor(CONST XMCOLOR *pSource);

用下面的方法存储数据,从XMVECTOR到XMFLOAT*

VOID XMStoreFloat3(XMFLOAT3 *pDestination,FXMVECTOR V);

......

3.Parameter Passing参数传递

龙书中主要介绍了CXMVECTOR 和FXMVECTOR 这两种参数类型,并告诉了我们在定义函数时,参数类型的注意事项:

函数的前三个XMVECTOR类型必须是FXMVECTOR,而后面的都是CXMVECTOR。

4.Constant Vectors常向量

需要初始化的XMVECTOR常量应该定义为XMVECTORF32类型(用于存储浮点向量)或XMVECTORU32类型(用于存储整数向量).

5.Vector Functions一些向量运算有关的函数

XMVECTOR XMVectorZero();//返回零向量

XMVECTOR XMVectorSplatOne();//返回(1,1,1,1)

XMVECTOR XMVectorSet(FLOAT x,FLOAT y,FLOAT z,FLOAT w);//返回(x,y,z,w)

XMVECTOR XMVectorReplicate(FLOAT s);//返回(s,s,s,s)

XMVECTOR XMVectorSplatX(FXMVECTOR V);//返回(vx,vx,vx,vx)

XMVECTOR XMVector3Length(FXMVECTOR V);//返回向量v的模所构成的新的向量,例如向量v模为2,则返回(2,2,2)

XMVECTOR XMVector3LengthSq(FXMVECTOR V);//模的平方

XMVECTOR XMVector3Dot(FXMVECTOR V1,FXMVECTOR V2);//点积

XMVECTOR XMVector3Cross(FXMVECTOR V1,FXMVECTOR V2);//叉积

XMVECTOR XMVector3Normalize(FXMVECTOR V);//单位化

XMVECTOR XMVector3Orthogonal(FXMVECTOR V);//得到一个与其垂直的向量

XMVECTOR XMVector3AngleBetweenVectors(FXMVECTOR V1,FXMVECTOR V2);//两个向量的夹角

VOID XMVector3ComponentsFromNormal(XMVECTOR* pParallel,XMVECTOR* pPerpendicular,FXMVECTOR V,FXMVECTOR Normal);//向量的投影

BOOL XMVector3Equal(FXMVECTOR V1,FXMVECTOR V2);//判断两个向量是否相等

6.Floating-Point Error浮点数计算误差

用浮点数进行计算(甚至单纯地表示)时,会出现误差,所以等判断相等时,需要定义一个容许误差。

附:dx11龙书测试的源码及测试结果

1.

 #include <windows.h>
#include <xnamath.h>
#include <iostream>
using namespace std; //重载<<操作符
ostream& operator<<(ostream &os, FXMVECTOR v)
{
XMFLOAT3 dest;
XMStoreFloat3(&dest, v);
os << "(" << dest.x << "," << dest.y << "," << dest.z << ")";
return os;
} int main()
{
cout.setf(ios_base::boolalpha);//cout格式化 输入输出bool值可以为true和false //检查是否支持SSE2
if (!XMVerifyCPUSupport())
{
cout << "xna math not supported" << endl;
return ;
}
XMVECTOR p = XMVectorZero();
XMVECTOR q = XMVectorSplatOne();
XMVECTOR u = XMVectorSet(1.0f, 2.0f, 3.0f, 0.0f);
XMVECTOR v = XMVectorSplatX(u);
XMVECTOR w = XMVectorReplicate(-3.5f); cout << "p = " << p << endl;
cout << "q = " << q << endl;
cout << "u = " << u << endl;
cout << "v = " << v << endl;
cout << "w = " << w << endl; return ;
}

2.

 #include <windows.h>
#include <xnamath.h>
#include <iostream>
using namespace std; ostream& operator<<(ostream &os, FXMVECTOR v)
{
XMFLOAT3 dest;
XMStoreFloat3(&dest, v);
os << "(" << dest.x << "," << dest.y << "," << dest.z << ")";
return os;
} int main()
{
cout.setf(ios_base::boolalpha);
if (!XMVerifyCPUSupport())
{
cout << "xna math not supported" << endl;
return ;
}
XMVECTOR n = XMVectorSet(1.0f, 0.0f, 0.0f, 0.0f);
XMVECTOR u = XMVectorSet(1.0f, 2.0f, 3.0f, 0.0f);
XMVECTOR v = XMVectorSet(-2.0f, 1.0f, -3.0f, 0.0f);
XMVECTOR w = XMVectorSet(0.707f, 0.707f, 0.0f, 0.0f); XMVECTOR a = u + v;
XMVECTOR b = u - v;
XMVECTOR c = 10.0f * u;
XMVECTOR L = XMVector3Length(u);
XMVECTOR d = XMVector3Normalize(u);
XMVECTOR s = XMVector3Dot(u, v);
XMVECTOR e = XMVector3Cross(u, v); XMVECTOR projW;
XMVECTOR perpW;
XMVector3ComponentsFromNormal(&projW, &perpW, w, n); bool equal = XMVector3Equal(projW + perpW, w) != ;
bool notEqual = XMVector3NotEqual(projW + perpW, w) != ;
XMVECTOR angelVec = XMVector3AngleBetweenVectors(projW, perpW);
float angleRadians = XMVectorGetX(angelVec);
float angleDegrees = XMConvertToDegrees(angleRadians); cout << "u = " << u << endl;
cout << "v = " << v << endl;
cout << "w = " << w << endl;
cout << "n = " << n << endl;
cout << "a = u + v = " << a << endl;
cout << "b = u - v = " << b << endl;
cout << "c = 10 * u = " << c << endl;
cout << "d = u / ||u|| = " << d << endl;
cout << "e = u x v = " << e << endl;
cout << "L = ||u|| = " << L << endl;
cout << "s = u.v = " << s << endl;
cout << "projW = " << projW << endl;
cout << "perpW = " << perpW << endl;
cout << "projW + perpW == w = " << equal << endl;
cout << "projW + perpW != w = " << notEqual << endl;
cout << "angle = " << angleDegrees << endl; return ;
}

3.

 #include <windows.h> // for FLOAT definition
#include <xnamath.h>
#include <iostream>
using namespace std; int main()
{
cout.precision(); // Check support for SSE2 (Pentium4, AMD K8, and above).
if( !XMVerifyCPUSupport() )
{
cout << "xna math not supported" << endl;
return ;
} XMVECTOR u = XMVectorSet(1.0f, 1.0f, 1.0f, 0.0f);
XMVECTOR n = XMVector3Normalize(u); float LU = XMVectorGetX(XMVector3Length(n)); // Mathematically, the length should be 1. Is it numerically?
cout << LU << endl;
if( LU == 1.0f )
cout << "Length 1" << endl;
else
cout << "Length not 1" << endl; // Raising 1 to any power should still be 1. Is it?
float powLU = powf(LU, 1.0e6f);
cout << "LU^(10^6) = " << powLU << endl;
}

Directx11学习笔记【五】 基本的数学知识----向量篇的更多相关文章

  1. 3D Game Programming withDX11 学习笔记(一) 数学知识总结

    在图形学中,数学是不可或缺的一部分,所以本书最开始的部分就是数学知识的复习.在图形学中,最常用的是矢量和矩阵,所以我根据前面三个章节的数学知识,总结一下数学知识. 一.矢量 数学中的矢量,拥有方向和长 ...

  2. DirectX11 学习笔记6 - 使用D3DXMATH数学库的一个样例

    这个样例是在之前的样例基础上 .把之前d3dx10math数学库换成了最新的d3dxmath.长处就不说了.先上效果图 所有代码.以及效果文件 文件结构 所有代码: 依照上图的文件顺序 #pragma ...

  3. C#可扩展编程之MEF学习笔记(五):MEF高级进阶

    好久没有写博客了,今天抽空继续写MEF系列的文章.有园友提出这种系列的文章要做个目录,看起来方便,所以就抽空做了一个,放到每篇文章的最后. 前面四篇讲了MEF的基础知识,学完了前四篇,MEF中比较常用 ...

  4. Directx11学习笔记【九】 3D渲染管线

    原文:Directx11学习笔记[九] 3D渲染管线 原文地址:http://blog.csdn.net/bonchoix/article/details/8298116 3D图形学研究的基本内容,即 ...

  5. HTML+CSS学习笔记 (7) - CSS样式基本知识

    HTML+CSS学习笔记 (7) - CSS样式基本知识 内联式css样式,直接写在现有的HTML标签中 CSS样式可以写在哪些地方呢?从CSS 样式代码插入的形式来看基本可以分为以下3种:内联式.嵌 ...

  6. (转)Qt Model/View 学习笔记 (五)——View 类

    Qt Model/View 学习笔记 (五) View 类 概念 在model/view架构中,view从model中获得数据项然后显示给用户.数据显示的方式不必与model提供的表示方式相同,可以与 ...

  7. java之jvm学习笔记五(实践写自己的类装载器)

    java之jvm学习笔记五(实践写自己的类装载器) 课程源码:http://download.csdn.net/detail/yfqnihao/4866501 前面第三和第四节我们一直在强调一句话,类 ...

  8. Directx11学习笔记【二十二】 用高度图实现地形

    本文由zhangbaochong原创,转载请注明出处http://www.cnblogs.com/zhangbaochong/p/5827714.html 在前面我们曾经实现过简单的地形(Direct ...

  9. Directx11学习笔记【二】 将HelloWin封装成类

    我们把上一个教程的代码封装到一个类中来方便以后的使用. 首先新建一个空工程叫做MyHelloWin,添加一个main.cpp文件,然后新建一个类叫做MyWindow,将于窗体有关的操作封装到里面 My ...

随机推荐

  1. PHP操作Mysql中间BLOB场

    1.MySQL在BLOB字段类型 BLOB场的类型用于存储二进制数据. MySQL在.BLOB它是一种类型的一系列.含有:TinyBlob.Blob.MediumBlob.LongBlob.大小上不同 ...

  2. 【ALearning】第二章 Androidproject知识介绍

    本章介绍了主要的初步Androidproject成立了一个开发环境.为了Android意识的整体项目和理解.本章包含Android开发环境的搭建.第一Android工程Hello World与Andr ...

  3. ASA IPSEC VPN配置

    ASA-1配置 : Saved:ASA Version 8.0(2) !hostname ASA-1enable password 8Ry2YjIyt7RRXU24 encryptednames!in ...

  4. Kafka - SQL 引擎

    Kafka - SQL 引擎分享 1.概述 大多数情况下,我们使用 Kafka 只是作为消息处理.在有些情况下,我们需要多次读取 Kafka 集群中的数据.当然,我们可以通过调用 Kafka 的 AP ...

  5. HashMap-死锁导致cpu占用100%分析(转)

    最近项目里面的一段千年代码出了问题,这个问题以前也出现过,不过不是那么明显,这次迁移机器由以前的4台机子变成2台以后问题被放大,最终不得不解决,特此分析一下. 先放出问题的代码 ? 1 2 3 4 5 ...

  6. winfrom 倒计时控件

    最近在做一个快递柜项目,要求在用户没有操作的时间到了一分钟,自动返回主页,我于是封装了一个倒计时控件,废话少说,直接上代码 public partial class RemainingTimeUC : ...

  7. 如何实现MySQL随机查询数据与MySQL随机更新数据?

    以下的文章主要介绍的是MySQL随机选取数据,对实现MySQ随机查询数据与MySQ随机更新数据的实际操作步骤的描述,以及对其实际操作中所要用到的语句的描述,以下就是对其具体操作步骤的描述. MySQL ...

  8. 动态接口服务 webservice

    private void GetDll() { WebClient client = new WebClient(); string url = "http://xxxx/services/ ...

  9. Apache Phoenix JDBC 驱动和Spring JDBCTemplate的集成

    介绍:Phoenix查询引擎会将SQL查询转换为一个或多个HBase scan,并编排运行以生成标准的JDBC结果集. 直接使用HBase API.协同处理器与自己定义过滤器.对于简单查询来说,其性能 ...

  10. Intel baytrail-t support Linux?

    点击这里查看文章 有空试试---唉... Ubuntu (Linux) on Atom Z3700 Series ASUS Transformer Book T100 is particularly ...