第119讲 新的征程(向量)

晃悠晃悠的我们的课程已经说了两年多了,犹记当初不知怎么表达而说得稀里糊涂到后来说到哪里我自己都搞不清状况,想来也是好笑,大家也就当我姑妄言之且姑妄信之吧,好吧,既然大家都比较对DirectX感兴趣,那么今年我们就来简单的熟悉3D引擎DirectX11吧。

本来说好接下来要说正则表达式的,但是大家对DirectX的呼声这么高那就好吧,我们暂且不去说C++的事,毕竟光说那些稀奇古怪的语法不但把大家都搞晕了而我自己有时候回头去看自己曾经写过的东西我都怀疑这真是我写的吗?哎,真尼玛高深啊,说笑了,好吧,我们开始进入正题。

向量,今天我们要说的就是向量,说到向量,其实大家都已经比较清楚的了,不过可能时间久了我们就生疏了,所以这一讲我们就来重温一下向量,因为向量在3D绘图中扮演着很重要的角色。

在三维空间中我们通常表示一个向量为:P(x,y,z),但是在3D绘图中我们通常用四维来表示一个向量为什么呢?好吧,等到下一讲我们说矩阵的时候就明白了。

P1(x1,y1,z1),P2(x2,y2,z2);

P1 + P2 = (x1 + x2,y1 + y2,z1 + z2);

那么两个向量加减的物理意义是什么?其实很简单,就是变换,比如物体的移动等等。

a.P1 = (a.x1,a.y1,a.z1)

向量和常数的乘除法表示的物体的缩放。

P1.P2 = x1.x2 + y1.y2 + z1.z2;

两个向量的点乘的意义是什么呢?

因为点乘还有一种写法:

P1.P2 = ||P1||.||P2||.cos(angle);

所以这里可以计算出两向量的夹角。

P1 X P2 = (y1.z2 – z1.y2,x1.z2 – z1.x2,z1.y2 – y1.x2)

两个向量的叉乘得到的和P1和P2正交的正交向量。


刚才我们说在DirectX中都是用四维来表示顶点或者向量,因为在计算机图形学中使用的都是齐次坐标,而其次坐标就是在原本的维度上再加一维来表示,所以原本的三维顶点就变成了四维,在DirectX中,在三维坐标系统顶点P(x,y,z)的齐次坐标为(x,y,z,1),而向量的第四维为0.当然顶点的第四维不一定是1,只要是非0都可以表示,因为这是有用处的,而通常我们也可以通过第四维来判断一个顶点倒是三维坐标系统的点呢还是表示一个向量呢?如果第四维是0那么就是向量,如果非零表示的就是点。


在DirectX11中,我们通常使用XNA数学库计算向量和矩阵,XNA库是DirectX11 SDK的一部分,在DirectX11之前所使用的数学库是D3DXMath库,不过大家要是对这个库熟悉的话DirectX11依然支持这个库的,我们使用XNA数学库只需要包含xnamath.h头文件即可,这个库的最基本类型是XMVECTOR ,这是一个typedef,他真正的原型是__m128,而这个类型是针对一个可映射至SIMD寄存器的变量定义,这个定义有些复杂,这里不多说。我们只需要知道怎么使用XNA数学库就好了。

XMVECTOR和普通类型一样,他重载了大量的数学常用操作符,比如+-*/等等,他是实现XNA库的基础,那么接下来我们看看XNA库的向量操作。


#include <D3d11/D3D11.h>

#include <D3d11/D3DX11.h>

#include <D3d11/DxErr.h>

#include <D3d11/d3dx11effect.h>

#include <D3d11/D3Dcompiler.h>

#include <D3d11/xnamath.h>

std::ostream&

operator<<(std::ostream&

os, XMVECTOR u){

os <<"

("

<<XMVectorGetX(u) <<"

,"

<<XMVectorGetY(u) <<"

,"

<<XMVectorGetZ(u) <<"

,"

<<XMVectorGetW(u) <<"

)"

<<std::endl;


return os;

}


int main(){

// 创建两个向量

XMVECTOR u = XMVectorSet(1.f, 2.f, 3.f, 1.f);

XMVECTOR v = XMVectorSet(1.f, 1.f, 1.f, 1.f);


XMVECTOR a, b, c, d, e, f, g, h, i;


// 向量加法

a = u + v;


// 向量减法

b = u – v;


// 向量乘以常数

c = 10 * u;


// 向量点乘

d = XMVector3Dot(u, v);


// 四维点乘

e = XMVector4Dot(u, v);


// 叉乘

f = XMVector3Cross(u, v);


// 向量规范化

g = XMVector4Normalize(u);


h = XMVector3Length(u);


i = XMVector4Length(u);


std::cout <<"

u + v = "

<<a <<std::endl;

std::cout <<"

u – v = "

<<b <<std::endl;

std::cout <<"

10*u  

= "

<<c <<std::endl;

std::cout <<"

u.v  

= "

<<d <<std::endl;

std::cout <<"

u.v  

= "

<<e <<std::endl;

std::cout <<"

uXv  

= "

<<
f <<std::endl;

std::cout <<"

Normalize of u  

= "

<<g <<std::endl;

std::cout <<"

Length of u  

= "

<<h <<std::endl;

std::cout <<"

Length of u  

= "

<<i <<std::endl;


return 0;

}


向量的基本操作掌握这些就差不多了。下一讲我们来说矩阵。

第119讲   新的征程(向量)

//=================================

回复D查看目录,回复数字查看相应章节


原文始发于微信公众号(

C/C++的编程教室

):第119讲 新的征程(向量)

|

发表评论