第03讲 顶点坐标变换.docx

上传人:b****7 文档编号:26135473 上传时间:2023-06-17 格式:DOCX 页数:44 大小:553.26KB
下载 相关 举报
第03讲 顶点坐标变换.docx_第1页
第1页 / 共44页
第03讲 顶点坐标变换.docx_第2页
第2页 / 共44页
第03讲 顶点坐标变换.docx_第3页
第3页 / 共44页
第03讲 顶点坐标变换.docx_第4页
第4页 / 共44页
第03讲 顶点坐标变换.docx_第5页
第5页 / 共44页
点击查看更多>>
下载资源
资源描述

第03讲 顶点坐标变换.docx

《第03讲 顶点坐标变换.docx》由会员分享,可在线阅读,更多相关《第03讲 顶点坐标变换.docx(44页珍藏版)》请在冰豆网上搜索。

第03讲 顶点坐标变换.docx

第03讲顶点坐标变换

顶点坐标变换

1、坐标系

(1)、左手法则:

(2).世界坐标系

世界坐标系也被称作全局坐标系,它用于建立一个描述其他坐标系所需要的参考框架,以便指定物体在该坐标系中的位置、方向及大小,如下图所示。

(3)局部坐标系

局部坐标系又被称作模型坐标系,用于描述物体自身属性的独立坐标系。

局部坐标系相对于物体的中心位置构成一个模型空间,如下图所示。

(4)观察坐标系

观察坐标系是与观察者密切相关的坐标系,用于指定观察三维空间中的物体的方向和位置。

观察坐标系的原点指定了摄像机(即观察视角)的位置,而左手坐标系统中的x轴和y轴描述摄像机的x和y方向上的正方向,而z轴正方向描述了观察的方向,如下图所示。

2、D3d中的向量定义

在D3DX库中,我们能用D3DXVECTOR3类表示3维空间中的向量。

它的定义是:

typedefstructD3DXVECTOR3:

publicD3DVECTOR

{

public:

D3DXVECTOR3(){};

D3DXVECTOR3(CONSTFLOAT*);

D3DXVECTOR3(CONSTD3DVECTOR&);

D3DXVECTOR3(CONSTD3DXFLOAT16*);

D3DXVECTOR3(FLOATx,FLOATy,FLOATz);

//casting

operatorFLOAT*();

operatorCONSTFLOAT*()const;

//assignmentoperators

D3DXVECTOR3&operator+=(CONSTD3DXVECTOR3&);

D3DXVECTOR3&operator-=(CONSTD3DXVECTOR3&);

D3DXVECTOR3&operator*=(FLOAT);

D3DXVECTOR3&operator/=(FLOAT);

//unaryoperators

D3DXVECTOR3operator+()const;

D3DXVECTOR3operator-()const;

//binaryoperators

D3DXVECTOR3operator+(CONSTD3DXVECTOR3&)const;

D3DXVECTOR3operator-(CONSTD3DXVECTOR3&)const;

D3DXVECTOR3operator*(FLOAT)const;

D3DXVECTOR3operator/(FLOAT)const;

friendD3DXVECTOR3operator*(FLOAT,CONSTstructD3DXVECTOR3&);

BOOLoperator==(CONSTD3DXVECTOR3&)const;

BOOLoperator!

=(CONSTD3DXVECTOR3&)const;

}D3DXVECTOR3,*LPD3DXVECTOR3;

(1)计算向量的大小:

FLOATD3DXVec3Length(//Returnsthemagnitude.

CONSTD3DXVECTOR3*pV//Thevectortocomputethelengthof.

);

D3DXVECTOR3v(1.0f,2.0f,3.0f);

floatmagnitude=D3DXVec3Length(&v);//=sqrt(14)

(2)标准化向量(单位化):

D3DXVECTOR3*D3DXVec3Normalize(

D3DXVECTOR3*pOut,//Result.

CONSTD3DXVECTOR3*pV//Thevectortonormalize.

);

(3)向量的点积:

FLOATD3DXVec3Dot(//Returnstheresult.

CONSTD3DXVECTOR3*pV1,//Leftsidedoperand.

CONSTD3DXVECTOR3*pV2//Rightsidedoperand.

);

D3DXVECTOR3u(1.0f,-1.0f,0.0f);

D3DXVECTOR3v(3.0f,2.0f,1.0f);

//1.0*3.0+-1.0*2.0+0.0*1.0

//=3.0+-2.0

floatdot=D3DXVec3Dot(&u,&v);//=1.0

(4)向量的叉积:

D3DXVECTOR3*D3DXVec3Cross(

D3DXVECTOR3*pOut,//Result.

CONSTD3DXVECTOR3*pV1,//Leftsidedoperand.

CONSTD3DXVECTOR3*pV2//Rightsidedoperand.

);

你能通过左手法则确定叉积返回的向量。

按照第一个向量指向第二个向量弯曲你的左手,这时拇指所指的方向就是叉积向量所指的方向。

(5)向量使用实例:

#include

#include

intmain(){

//二维向量C2=A2-B2

D3DXVECTOR2A2(6.0f,3.0f);

D3DXVECTOR2B2(4.0f,2.0f);

D3DXVECTOR2C2=A2-B2;

printf("二维向量C2=A2-B2=(6.0f,3.0f)-(4.0f,2.0f)=(%f,%f)\n",C2.x,C2.y);

//三维向量C3=A3-B3

D3DXVECTOR3A3(5.0f,2.6f,10.f);

D3DXVECTOR3B3(2.0f,3.4f,3.0f);

D3DXVECTOR3C3=A3-B3;

printf("三维向量C3=A3-B3=(5.0f,2.6f,10.f)-(2.0f,3.4f,3.0f)=(%f,%f,%f)\n",

C3.x,C3.y,C3.z);

//三维向量点积d=u.v,叉积w=uxv

D3DXVECTOR3u(5.0f,2.6f,10.f);

D3DXVECTOR3v(2.0f,3.4f,3.0f);

floatd;

d=D3DXVec3Dot(&u,&v);

printf("三维向量点积d=u.v=(5.0f,2.6f,10.f).(2.0f,3.4f,3.0f)=(%f)\n",d);

D3DXVECTOR3w;

D3DXVec3Cross(&w,&u,&v);

printf("三维向量叉积w=uxv=(5.0f,2.6f,10.f)x(2.0f,3.4f,3.0f)=((%f,%f,%f)\n",

w.x,w.y,w.z);

return0;

}

3、D3DX中的矩阵

(1)矩阵的概念:

在线性代数中,矩阵就是以行和列形式组织的矩形数字块。

可以使用m×n表示矩阵的组成,它表示该矩阵具有m行和n列。

例如,一个3×3的矩阵M和一个4×4的矩阵N的表示形式如下:

(2)单位矩阵

单位矩阵是一个特殊的方形矩阵,其中的对角线元素全部都是1,而非对角线元素都是0。

一个m×m的单位矩阵记作Im。

例如,3×3的单位矩阵Im和4×4的单位矩阵In如下:

(3)转置矩阵、逆矩阵、矩阵的加减(转置、逆、数乘)运算:

(4)矩阵乘法:

在某些情况下,两个矩阵可以相乘。

此时,参与相乘的第一个矩阵的列数必须与第二个矩阵的行数相同,其相乘得到的矩阵的行数为第一个矩阵的行数,而列数为第二个矩阵的列数。

例如,一个4×2的矩阵A与一个2×3的矩阵B相乘,其相乘的结果将是4×3的矩阵,记作AB。

(5)向量与矩阵的乘法

在将向量与矩阵相乘时,需要确定是将向量是看作行向量还是看作列向量。

其中,行向量只能够左乘矩阵,其相乘的结果仍是一个行向量;列向量只能够右乘矩阵,其相乘的结果是一个列向量。

例如,一个3D向量V与一个3×3矩阵M相乘,其计算过程如下:

(6)D3DX中矩阵用法

当设计Direct3D应用程序时,使用4×4矩阵和1×4行矩阵(向量)是有代表性的。

注意使用这两种矩阵意味着可以进行下列定义的矩阵乘法。

向量-矩阵乘法:

即,假如1×4的单行矩阵V,和4×4的矩阵T,那么积VT可计算并且返回的结果是一个1×4的单行矩阵(向量)。

矩阵-矩阵乘法:

即,假如4×4的矩阵T,和4×4的矩阵R,那么积TR和RT可计算并且两者返回的结果都是一个4×4的矩阵。

注意因为矩阵乘法不满足交换律所以TR和RT不一定相等。

在D3DX中表示1×4的行矩阵(向量),我们用D3DXVECTOR3和D3DXVECTOR4向量类。

当然D3DXVECTOR3只有3个成员,不是4个。

然而,第4个成员缺省是1或0。

在D3DX中表示4×4的矩阵,我们用D3DXMATRIX类,定义如下:

typedefstructD3DXMATRIX:

publicD3DMATRIX{

public:

D3DXMATRIX(){};

D3DXMATRIX(CONSTFLOAT*);

D3DXMATRIX(CONSTD3DMATRIX&);

D3DXMATRIX(

FLOAT_11,FLOAT_12,FLOAT_13,FLOAT_14,

FLOAT_21,FLOAT_22,FLOAT_23,FLOAT_24,

FLOAT_31,FLOAT_32,FLOAT_33,FLOAT_34,

FLOAT_41,FLOAT_42,FLOAT_43,FLOAT_44

);

//accessgrants

FLOAT&operator()(UINTRow,UINTCol);

FLOAToperator()(UINTRow,UINTCol)const;

//castingoperators

operatorFLOAT*();

operatorCONSTFLOAT*()const;

//assignmentoperators

D3DXMATRIX&operator*=(CONSTD3DXMATRIX&);

D3DXMATRIX&operator+=(CONSTD3DXMATRIX&);

D3DXMATRIX&operator-=(CONSTD3DXMATRIX&);

D3DXMATRIX&operator*=(FLOAT);

D3DXMATRIX&operator/=(FLOAT);

//unaryoperators

D3DXMATRIXoperator+()const;

D3DXMATRIXoperator-()const;

//binaryoperators

D3DXMATRIXoperator*(CONSTD3DXMATRIX&)const;

D3DXMATRIXoperator+(CONSTD3DXMATRIX&)const;

D3DXMATRIXoperator-(CONSTD3DXMATRIX&)const;

D3DXMATRIXoperator*(FLOAT)const;

D3DXMATRIXoperator/(FLOAT)const;

friendD3DXMATRIXoperator*(FLOAT,CONSTD3DXMATRIX&);

BOOLoperator==(CONSTD3DXMATRIX&)const;

BOOLoperator!

=(CONSTD3DXMATRIX&)const;

}D3DXMATRIX,*LPD3DXMATRIX;//记住这个矩阵结构体名称,用来定义矩阵

typedefstruct_D3DMATRIX{

union{

struct{

float_11,_12,_13,_14;

float_21,_22,_23,_24;

float_31,_32,_33,_34;

float_41,_42,_43,_44;

};

floatm[4][4];

};

}D3DMATRIX;

矩阵单位化运算函数:

D3DXMATRIX*D3DXMatrixIdentity(

D3DXMATRIX*pout//将矩阵转换为单位矩阵

);

D3DXMATRIXM;

D3DXMatrixIdentity(&M);//M=单位矩阵

矩阵乘法函数:

D3DXMATRIX*D3DXMatrixMultiply(

D3DXMATRIX*pOut,

CONSTD3DXMATRIX*pM1,

CONSTD3DXMATRIX*pM2

);

pOut=pM1*pM2;

4、矩阵的基本变换

平移变换:

平移变换是对3D空间中某点P(x,y,z),分别沿X、Y、Z坐标轴平移dx、dy和dz个单位,那么点P平移后所处的位置的坐标可以通过以下公式计算:

如果将P点的坐标以3D齐次坐标表示(x,y,z,w=1),并且在计算新位置的坐标时,同时将齐次坐标的每个分量都参与计算,那么点坐标的计算公式就为:

然后将公式中除齐次坐标分量外的所有因子构成一个4×4的矩阵,那么就得到一个平移变换矩阵:

则:

对3D空间中某点P(x,y,z,1),分别沿X、Y、Z坐标轴平移dx、dy和dz个单位,那么点P平移后所处的位置的坐标P’(x’,y’,z’,1)可以通过以下公式计算:

P’=PT

在D3DX中矩阵平移的函数是:

D3DXMATRIX*D3DXMatrixTranslation(

D3DXMATRIX*pOut,//返回平移后的矩阵.

FLOATx,//x轴移动的单位

FLOATy,//y轴移动的单位

FLOATz//z轴移动的单位

);

世界变换包括平移、旋转和缩放变换,可以通过D3DX库中D3DXMatrixTranslation、D3DXMatrixRotation*和D3DXMatrixSaling函数实施变换,并得到一个世界变换矩阵。

然后调用IDirect3DDevice9接口的SetTransform方法应用世界变换。

SetTransform方法的声明如下:

HRESULTIDirect3DDevice9:

:

SetTransform(

D3DTRANSFORMSTATETYPEState,//变换的类型

CONSTD3DMATRIX*pMatrix//应用的变换矩阵

);

其中,State参数是一个D3DTRANSFORMSTATETYPE枚举类型,用于表示应用变换的类型,其枚举值D3DTS_WORLD、D3DTS_VIEW、D3DTS_PROJECTION分别表示进行世界变换、取景变换和投影变换。

 

平移变换完整代码实例:

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

//Desc:

坐标变换

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

#include

#include//D3DX实用库函数,该头文件中又包含了d3d9.h头文件

//-----------------------------------------------------------------------------

//Desc:

全局变量

//-----------------------------------------------------------------------------

LPDIRECT3D9g_pD3D=NULL;//Direct3D对象

LPDIRECT3DDEVICE9g_pd3dDevice=NULL;//Direct3D设备对象

LPDIRECT3DVERTEXBUFFER9g_pVB=NULL;//顶点缓冲区对象

HWNDg_Wnd=NULL;//窗口句柄

//-----------------------------------------------------------------------------

//Desc:

顶点结构

//-----------------------------------------------------------------------------

structCUSTOMVERTEX

{

D3DXVECTOR3position;

DWORDcolor;

};

#defineD3DFVF_CUSTOMVERTEX(D3DFVF_XYZ|D3DFVF_DIFFUSE)

/*以下的观察变换、投影和视口变换*/

//-----------------------------------------------------------------------------

//Desc:

设置观察矩阵和投影矩阵

//-----------------------------------------------------------------------------

VOIDSetupViewandProjMatrices()

{

//建立并设置观察矩阵

D3DXVECTOR3vEyePt(0.0f,3.0f,-20.0f);

D3DXVECTOR3vLookatPt(0.0f,0.0f,0.0f);

D3DXVECTOR3vUpVec(0.0f,1.0f,0.0f);

D3DXMATRIXmatView;

D3DXMatrixLookAtLH(&matView,&vEyePt,&vLookatPt,&vUpVec);

g_pd3dDevice->SetTransform(D3DTS_VIEW,&matView);

//建立并设置投影矩阵

D3DXMATRIXmatProj;

D3DXMatrixPerspectiveFovLH(&matProj,D3DX_PI/4,1.0f,1.0f,100.0f);

g_pd3dDevice->SetTransform(D3DTS_PROJECTION,&matProj);

}

//-----------------------------------------------------------------------------

//Desc:

设置视区

//-----------------------------------------------------------------------------

VOIDSetupViewPort()

{

RECTrect;

GetClientRect(g_Wnd,&rect);

D3DVIEWPORT9vp;

vp.X=0;

vp.Y=0;

vp.Width=rect.right;

vp.Height=rect.bottom;

vp.MinZ=0.0f;

vp.MaxZ=1.0f;

g_pd3dDevice->SetViewport(&vp);

}

//-----------------------------------------------------------------------------

//Desc:

初始化Direct3D

//-----------------------------------------------------------------------------

HRESULTInitD3D(HWNDhWnd)

{

//创建Direct3D对象,该对象用于创建Direct3D设备对象

if(NULL==(g_pD3D=Direct3DCreate9(D3D_SDK_VERSION)))

returnE_FAIL;

//设置D3DPRESENT_PARAMETERS结构,准备创建Direct3D设备对象

D3DPRESENT_PARAMETERSd3dpp;

ZeroMemory(&d3dpp,sizeof(d3dpp));

d3dpp.Windowed=TRUE;

d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD;

d3dpp.BackBufferFormat=D3DFMT_UNKNOWN;

//创建Direct3D设备对象

if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hWnd,

D3DCREATE_SOFTWARE_VERTEXPROCESSING,

&d3dpp,&g_pd3dDevice)))

{

returnE_FAIL;

}

//设置剔出模式为不剔出任何面(正面和反面)

//g_pd3dDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE);

//关闭光照处理,默认情况下启用光照处理

g_pd3dDevice->SetRenderState(D3DRS_LIGHTING,FALSE);

//设置观察和投影矩阵

SetupViewandProjMatrices();

//设置视区

SetupViewPort();

returnS_OK;

}

//-----------------------------------------------------------------------------

//Desc:

创建场景图形

//-----------------------------------------------------------------------------

HRESULTInitVB()

{

//顶点数据

CUSTOMVERTEXvertices[]=

{

{D3DXVECTOR3(1.0f,4.0f,0.5f),0xffff0000},

{D3DXVECTOR3(3.0f,5.0f,0.5f),0xf

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 数学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1