绕任意轴旋转.docx

上传人:b****4 文档编号:4287924 上传时间:2023-05-06 格式:DOCX 页数:13 大小:160.60KB
下载 相关 举报
绕任意轴旋转.docx_第1页
第1页 / 共13页
绕任意轴旋转.docx_第2页
第2页 / 共13页
绕任意轴旋转.docx_第3页
第3页 / 共13页
绕任意轴旋转.docx_第4页
第4页 / 共13页
绕任意轴旋转.docx_第5页
第5页 / 共13页
绕任意轴旋转.docx_第6页
第6页 / 共13页
绕任意轴旋转.docx_第7页
第7页 / 共13页
绕任意轴旋转.docx_第8页
第8页 / 共13页
绕任意轴旋转.docx_第9页
第9页 / 共13页
绕任意轴旋转.docx_第10页
第10页 / 共13页
绕任意轴旋转.docx_第11页
第11页 / 共13页
绕任意轴旋转.docx_第12页
第12页 / 共13页
绕任意轴旋转.docx_第13页
第13页 / 共13页
亲,该文档总共13页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

绕任意轴旋转.docx

《绕任意轴旋转.docx》由会员分享,可在线阅读,更多相关《绕任意轴旋转.docx(13页珍藏版)》请在冰点文库上搜索。

绕任意轴旋转.docx

绕任意轴旋转

几何变换详解

在三维图形学中,几何变换大致分为三种,平移变换(Translation),缩放变换(Scaling),旋转变换(Rotation)。

以下讨论皆针对DirectX,所以使用左手坐标系。

平移变换

将三维空间中的一个点[x,y,z,1]移动到另外一个点[x',y',z',1],三个坐标轴的移动分量分别为dx=Tx,dy=Ty,dz=Tz,即

x'=x+Tx

y'=y+Ty

z'=z+Tz

平移变换的矩阵如下。

缩放变换

将模型放大或者缩小,本质也是对模型上每个顶点进行放大和缩小(顶点坐标值变大或变小),假设变换前的点是[x,y,z,1],变换后的点是[x',y',z',1],那么

x'=x*Sx

y'=y*Sy

z'=z*Sz

缩放变换的矩阵如下。

旋转变换

这是三种变换中最复杂的变换,这里只讨论最简单的情况,绕坐标轴旋转,关于绕任意轴旋转,在后续的随笔中介绍。

绕X轴旋转

绕X轴旋转时,顶点的x坐标不发生变化,y坐标和z坐标绕X轴旋转θ度,旋转的正方向为顺时针方向(沿着旋转轴负方向向原点看)。

[x,y,z,1]表示变换前的点,[x',y',z',1]表示变换后的点。

变换矩阵如下。

关于旋转的正方向,OpenGL与多数图形学书籍规定旋转正方向为逆时针方向(沿着坐标轴负方向向原点看),比如ComputerGraphicsCVersion,p409。

绕Y轴旋转

绕Y轴旋转时,顶点的y坐标不发生变化,x坐标和z坐标绕Y轴旋转θ度。

[x,y,z,1]表示变换前的点,[x',y',z',1]表示变换后的点。

变换矩阵如下。

绕Z轴旋转

绕Z轴旋转时,顶点的z坐标不发生变化,x坐标和y坐标绕Z轴旋转θ度。

[x,y,z,1]表示变换前的点,[x',y',z',1]表示变换后的点。

变换矩阵如下。

绕坐标轴旋转的矩阵推导

上面三个旋转矩阵是如何得来的呢?

我们推导一下,首先看一下二维的情况,再扩展到三维即可。

实际上上面三种绕坐标轴旋转的情况属于特殊的二维旋转,比如绕Z轴旋转,相当于在与XOY平面上绕原点做二维旋转。

假设点P(x,y)是平面直角坐标系内一点,其到原点的距离为r,其与X轴的夹角为A,现将点P绕原点旋转θ度,得到点P'(x',y'),P'与X轴的夹角为B,则A=B-θ。

(注意,在二维坐标中,逆时针旋转时角度为正,顺时针旋转时角度为负,下图中由P旋转到P',角度为θ,若是由P'转到P,则角度为-θ)。

于是可得下面的转换方程

(式一)

写成矩阵的形式就是

求得旋转矩阵为

由于这里使用齐次坐标,所以还需加上一维,最终变成如下形式

绕Z轴旋转矩阵

和前面给出的绕Z轴旋转矩阵完全吻合。

对于绕X轴旋转的情况,我们只需将式一中的x用y替换,y用z替换,z用x替换即可。

替换后得到

(式二)

对应的旋转矩阵为

绕X轴旋转矩阵

对于绕Y轴旋转的情况,只需对式二做一次同样的替换即可,的到的变换方程为

对应的变换矩阵为

绕Y轴旋转矩阵

逆矩阵

平移变换矩阵的逆矩阵与原来的平移量相同,但是方向相反。

旋转变换矩阵的逆矩阵与原来的旋转轴相同但是角度相反。

缩放变换的逆矩阵正好和原来的效果相反,如果原来是放大,则逆矩阵是缩小,如果原来是缩小,则逆矩阵是放大。

==HappyCoding==

作者:

zdd

出处:

绕任意轴旋转

绕任意轴旋转的情况比较复杂,主要分为两种情况,一种是平行于坐标轴的,一种是不平行于坐标轴的,对于平行于坐标轴的,我们首先将旋转轴平移至与坐标轴重合,然后进行旋转,最后再平移回去。

∙将旋转轴平移至与坐标轴重合,对应平移操作

∙旋转,对应操作

∙步骤1的逆过程,对应操作

整个过程就是

对于不平行于坐标轴的,可按如下方法处理。

(该方法实际上涵盖了上面的情况)

1将旋转轴平移至原点

2将旋转轴旋转至YOZ平面

3将旋转轴旋转至于Z轴重合

4绕Z轴旋转θ度

5执行步骤3的逆过程

6执行步骤2的逆过程

7执行步骤1的逆过程

假设用v1(a1,b2,c2)和v2(a2,b2,c2)来表示旋转轴,θ表示旋转角度。

为了方便推导,暂时使用右手系并使用列向量,待得出矩阵后转置一下即可,上面步骤对应的流程图如下。

步骤1是一个平移操作,将v1v2平移至原点,对应的矩阵为

步骤2是一个旋转操作,将p(p=v2-v1)旋转至XOZ平面,步骤3也是一个旋转操作,将p旋转至与Z轴重合,这两个操作对应的图如下。

做点p在平面YOZ上的投影点q。

再过q做Z轴垂线,则r是p绕X轴旋转所得,且旋转角度为α,且

于是旋转矩阵为

现在将r绕Y轴旋转至与Z轴重合,旋转的角度为-beta(方向为顺时针),且

于是得到旋转矩阵为

最后是绕Z轴旋转,对应的矩阵如下

如果旋转轴是过原点的,那么第一步和最后一步的平移操作可以省略,也就是把中间五个矩阵连乘起来,再转置一下,得到下面的绕任意轴旋转的矩阵

对应的函数代码如下。

voidRotateArbitraryAxis(D3DXMATRIX*pOut,D3DXVECTOR3*axis,floattheta)

{

D3DXVec3Normalize(axis,axis);

floatu=axis->x;

floatv=axis->y;

floatw=axis->z;

pOut->m[0][0]=cosf(theta)+(u*u)*(1-cosf(theta));

pOut->m[0][1]=u*v*(1-cosf(theta))+w*sinf(theta);

pOut->m[0][2]=u*w*(1-cosf(theta))-v*sinf(theta);

pOut->m[0][3]=0;

pOut->m[1][0]=u*v*(1-cosf(theta))-w*sinf(theta);

pOut->m[1][1]=cosf(theta)+v*v*(1-cosf(theta));

pOut->m[1][2]=w*v*(1-cosf(theta))+u*sinf(theta);

pOut->m[1][3]=0;

pOut->m[2][0]=u*w*(1-cosf(theta))+v*sinf(theta);

pOut->m[2][1]=v*w*(1-cosf(theta))-u*sinf(theta);

pOut->m[2][2]=cosf(theta)+w*w*(1-cosf(theta));

pOut->m[2][3]=0;

pOut->m[3][0]=0;

pOut->m[3][1]=0;

pOut->m[3][2]=0;

pOut->m[3][3]=1;

如果旋转轴是不过原点的,那么第一步和最后一步就不能省略,将所有七个矩阵连乘起来,得到如下变换矩阵

对应如下这个超长的矩阵,在这里(u,v,w)=(a2,b2,c2)-(a1,b1,c1),且是单位向量,a,b,c分别表示(a1,b1,c1)

将上面的过程写成函数,该函数接受四个参数,第一个参数是一个输出参数,用来保存得到的旋转矩阵,第二个和第三个参数是旋转轴的两个端点,最后一个参数是旋转角度θ,注意,在函数中我们已经将上面的矩阵转置了,因为上面是按照列向量计算的。

voidRotateArbitraryLine(D3DXMATRIX*pOut,D3DXVECTOR3*v1,D3DXVECTOR3*v2,floattheta)

{

floata=v1->x;

floatb=v1->y;

floatc=v1->z;

D3DXVECTOR3p=*v2-*v1;

D3DXVec3Normalize(&p,&p);

floatu=p.x;

floatv=p.y;

floatw=p.z;

floatuu=u*u;

floatuv=u*v;

floatuw=u*w;

floatvv=v*v;

floatvw=v*w;

floatww=w*w;

floatau=a*u;

floatav=a*v;

floataw=a*w;

floatbu=b*u;

floatbv=b*v;

floatbw=b*w;

floatcu=c*u;

floatcv=c*v;

floatcw=c*w;

floatcostheta=cosf(theta);

floatsintheta=sinf(theta);

pOut->m[0][0]=uu+(vv+ww)*costheta;

pOut->m[0][1]=uv*(1-costheta)+w*sintheta;

pOut->m[0][2]=uw*(1-costheta)-v*sintheta;

pOut->m[0][3]=0;

pOut->m[1][0]=uv*(1-costheta)-w*sintheta;

pOut->m[1][1]=vv+(uu+ww)*costheta;

pOut->m[1][2]=vw*(1-costheta)+u*sintheta;

pOut->m[1][3]=0;

pOut->m[2][0]=uw*(1-costheta)+v*sintheta;

pOut->m[2][1]=vw*(1-costheta)-u*sintheta;

pOut->m[2][2]=ww+(uu+vv)*costheta;

pOut->m[2][3]=0;

pOut->m[3][0]=(a*(vv+ww)-u*(bv+cw))*(1-costheta)+(bw-cv)*sintheta;

pOut->m[3][1]=(b*(uu+ww)-v*(au+cw))*(1-costheta)+(cu-aw)*sintheta;

pOut->m[3][2]=(c*(uu+vv)-w*(au+bv))*(1-costheta)+(av-bu)*sintheta;

pOut->m[3][3]=1;

}

 

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

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2