高级计算机图形学 中国科学技术大学计算机学院_第1页
高级计算机图形学 中国科学技术大学计算机学院_第2页
高级计算机图形学 中国科学技术大学计算机学院_第3页
高级计算机图形学 中国科学技术大学计算机学院_第4页
高级计算机图形学 中国科学技术大学计算机学院_第5页
已阅读5页,还剩50页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

高级计算机图形学

---------------------------\

中国科学技术大学计算机学院

黄章进

zhuang@

第四章之第四节

OpenGL中的变换

______________________J

基本内容寡占

•学习在OpenGL中如何进行变换

•旋转

•平移

•缩放

•平滑旋转技术

•四元数

•虚拟跟踪球

________________7

OpenGL中的标架

•根据绘制流水线中出现的先后顺序:

•对象或模型标架

世界标架

•眼或照相机标架

•裁剪标架

规范化设备标架

•窗口或屏幕标架

__________J

OpenGL中的表示建

•在模型标架中定义各个对象

•把对象放置到应用程序场景(世界标架)中

,用模型变换改变它们的大小、方向和位置

•用视图变换把场景变换到照相机标架中。

•标架变换对应到一个仿射变换,从模型坐标,世界

坐标->眼坐标的变换都可以用4x4矩阵表示

OpenGL把模型变换和视图变换合并为模-视变换,

对应矩阵为模-视矩阵

____________________________________________>

OpenGL中的表示

•投影变换把场景变换到裁剪标架中,视见体

变轨力裁剪立方体,然后把视见状外的对象

从场景里莪剪掉

•顶点的齐次裁剪坐标经过透视除法,即用w

分量去除其他分量,得到三维的规范化设备

坐标表示

•根据视口信息,把规范化设备坐标变换为三

维的窗口坐标

窗口坐标单位是像素,保留了深度信息

•去掉深度分量,就得到了二维的屏幕坐标

OpenGL中的矩阵三三当wfei

•在OpenGL中矩阵是状态的一部分

•有多种类型

•模型视图(GL_MODELVIEW)

•投影(GL_PROJECTION)

•纹理(GL_TEXTURE)(不讲)

•颜色(GL_COLOR)(不讲)

•用于操作的单组函数

•选择所操作的对象

•glMatrixMode(GL_MODELVIEW);

•glMatrixMode(GL_PROJECTION);

当前变换矩阵(CTM)

•从概念上说,当前变换矩阵(CTM)就是一

个4x4阶的齐次坐标矩阵,它是状态的一

部分,被应用到经过流水线中的所有顶点

•CTM是在应用程序中定义的,并被加载到

变换单元中―

p工顶点

顶点-----CTM

7

CTM运算

•CTM可以被改变,改变的方法是加载一个新的

CTM或者右乘一个矩阵

加载单位阵:c<—I

加载任意矩阵:C-M

加载一个平移矩阵:C-T

加载一个旋转矩阵:C-R

加载一个缩放矩阵:C-S

右乘任意矩阵:C—CM

右乘一个平移矩阵:C―CT

右乘一个旋转矩阵:C-CR

右乘一个缩放矩阵:C―CS

绕固定点的旋转

从单位阵开始:C<-I

把固定点移到原点:C―CT

旋转:C―CR

把固定点移回到原处:C―CT/

结果:C=TRT1是逆向的

这是做矩阵右乘的结果

注意:在程序中最后指定的运算是最先被执行的运算

倒转次序

我们想要得到C=T-1RT

所以必须按下面的次序进行运算

C<-I

C<-CT1

C—CR

C—CT

每个运算对应于程序中的一个函数调用

注意:在程序中最后指定的运算是最先被执行的运算

________________________________________>

OpenGL中的CTM夹

•在OpenGL的流水线中有一个模型视图矩阵和

一个投影矩阵,这两个矩阵复合在一起构成

CTM

•可以通过首先设置正确的矩阵模式处理每个矩

丁而占丁而占

­二►模型视图——A投影!—三►

I_____________I

I

CTM

旋转、平移、缩放

加载单位阵:

glLoadldentity()

右乘变换矩阵:

glRotatef(theta,vx,vy,vz)

•theta以角度为单位,(vx,vy,vz)定义旋转轴

glTranslatef(dx,dy,dz)

glScalef(sx,sy,sz)

每个函数的参数还可以是d(double)类型

示例

•固定点为(1。2。3.0),绕2轴旋转30。

glMatrixMode(GL_MODELVIEW);

glLoadldentity();//止匕命令不会才巴投影

矩阵重设

glTranslated(1.0,2.0,3.0);

glRotated(30.0^0・0,0.0,1.0);

glTranslatef(-1.0^-2・0,-3.0);

•记住在程序中最后指定的矩阵是最先被执行的

(操作J

任意矩阵

•可以加载应用程序中定义的矩阵,或者使

之与CTM相乘

glLoadMatrixf(m)

glMultMatrixf(m)

•矩阵m是有16个元素的一维数组,按列定

义了4x4矩阵

•^glMultMatrixf(m)中m右乘当前矩

阵,Op㊀nGL没提供左乘

任意矩阵

・16维向量m=(m0,m1..,nii5)指定的歹4主序知■

阵为

mom4m8mn

mmmm

M=x5913

加2m6miomi4

m3m7mnm15

•C语言定义的矩阵m[4][4]是行主序的,元素

m[i皿相当于OpenGL变换矩阵的洌j行元素。

为避免行列混淆,声明矩阵为m[16]

•许多情况中需要保存变换矩阵,待稍后再

•遍历层次数据结构

•当执行显示列表时避免状态改变

•OpenGL为每种类型的矩阵维持一个堆栈

应用下述函数处理矩阵堆栈(也是由

glMatrixMod㊀设置次巨阵类型)

glPushMatrix()

glPopMatrix()

读入后台矩阵

•OpenGL状态中有些信息是以矩阵形式保存的

•可以利用查询函数读入矩阵(以及其它部分的状态)

glGetIntegerv

glGetFloatv

glGetBooleanv

glGetDoublev

•例如,对于模型视图矩阵:

doublem[16];

glGetDoublev(GL_MODELVIEW_MATRIX,m);

______________________________________________J

变换的应用上士

•例如:应用空闲函数旋转立方体,鼠标函

数改变旋转的方向

•从一个画立方体的程序开始(cube©

立方体中心在原点

各方向与坐标轴平行

intmain(intargc,char**argv){

glutlnit(&argczargv);

glutlnitDisplayMode(GLUT_DOUBLE|GLUT_RGB|

GLUT_DEPTH);

glutlnitWindowSize(500,500);

glutCreateWindow(ncolorcube”);

glutReshapeFunc(myReshape);

glutDisplayFunc(display);

glutldleFunc(spinCube);

glutMouseFunc(mouse);

glEnable(GL_DEPTH_TEST);

glutMainLoop();

}

空闲与鼠标的回调函数

voidspinCube(){

theta[axis]+=2.0;

if(theta[axis]>360.0)

theta[axis]-=360.0;

glutPostRedisplay();

}

voidmouse(GLintbtnzGLintstate,GLintx,GLinty)

(

if(btn==GLUT_LEFT_BUTTON&&state==GLUT_DOWN)

axis=0;

if(btn==GLUT_MIDDLE_BUTTON&&state==GLUT_DOWN)

axis=1;

if(btn==GLUT_RIGHT_BUTTON&&state==GLUT_DOWN)

axis=2;

显示回调函数

voiddisplay(void){

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

glLoadldentity();

glRotatef(theta[0],1.0,0.0,0.0);

glRotatef(theta[1],0.0,1.0,0.0);

glRotatef(theta[2]z0.0,0.0,1.0);

colorcube();

glFlush();

glutSwapBuffers();

注意:由于回调函数的参数形式是固定的,类似于theta和axis等变量必

须定义为全局变量

照相机信息在标准的形状改变回调函数中定义

模型视图矩阵和投影矩阵

•在OpenGL中模型视图矩阵可以用来

・定位照相机

•可以利用旋转和平移,但通常采用gluLookat()会更简

•建立对象模型

•投影矩阵用来定义视景体以及选择照相机镜头

•虽然两者有同样的函数进行处理,但应用时必

须非常仔细,因为累加的改变总是右乘到CTM

Ji

例如,用同样的矩阵旋转模型视图矩阵和投影矩阵并不

是等价的操作。对模型视图矩阵的左乘等价于对投影矩

阵的右乘

_______________________________________7

平滑旋转

•从实用的观点来看,经常需要通过变换来

平滑移功和旋转一'个对彖

问题:找到一个模型视图矩阵序列Mo,Mi,

M〃使得当把它们依次作用到一个或多个好象上

时,得到平滑的变换效果

•在定向对象时,可以利用一个事实,那就

是任一旋转后应着球面上的文卤的一部分

•求出旋转轴与角度

教材:虚拟跟踪球

增量式旋转

•考虑两种途径

对于一组旋转矩阵Ro,Rj…,R神求出每个的

Euler角,再应用R,=R.RR/x

!//v

•不是很有效

•利用最终的位置确定旋转轴与旋转角度,再逐

步增加这个角度

•四元数方法比上述两种方法都有效

_________J

Hamilton,W.R.

•威廉•哈密顿1805-1865

•爱尔兰数学家、物理学家

•出生于1805年8月3日与4日的

午夜

•小时学习14种语言,17岁自

学数学

•1843四元数公式刻在

Brougham桥的石头上

•四十岁后成为酒鬼

/wiki/Quaternion

4*1・

四元数鼻一.

•四元数是把复数从二维到四维的不可交

换推广

•既含有标量又含有向量的表示

•有一个实部和三个虚部i,j,k

q=q0+q1i+q2j+q^i=(%,q)

•p_j2_^-2_jjk=-1

•向量q/i+qj+q3k

____________________________________________________________________________________________________J

四元数的运算事匹事;■

•加法:q+q'=(外+荻',q+q)

•乘法:qq'=(%而"qq',,o'q+%q'+q-q)

•共根:q*=(%,-q)

•长度:\qI=(%2+q.q)“2

•模:\qI2=QQ+Iql2=qq*

•单位元:乘法(1,0);加法(0,0)

•逆元:=g*/lqP=(%,-q)/lqI2

•单位四元数:|q|二1,有q-i=q*

axb=[a2b3-a3b2,a3b1-a1b3,a1b2-a2b1]

四元数与旋转

•四元数的向量部分表示空间点:p=(0,p)

•r~(cos9/2,sin^/2v),其中v#一个单位,

向量Sr/

•r是单位四元数^

r1-(cos8/2,-sinO/2v),

•p”=rp「T也是一个点,是恁♦绕方向v旋转

。角后的位置

固定点为原点

例子

•求出绕x轴和y轴旋转90。的四元数,并求

出其积

用r-(cos0/2,sin8/2v),0=90。,对X轴,

v二(L0,0),

.=乎(U,o,o)

类似的,々=*(1,0,1,0)

从而,rxry=1(1,1,1,1)

/-sweetser/java/qcalc/qcalc.html

SLERP-球面线性插值

•SphericalLinearintERPolation:沿最短圆

•当两个方向很接近时,采用线性插值避免

I除。

用四元数定义旋转注国BB联

•四元数可以表示在球面上的平滑旋转,而

且非常有效。

•处理过程为

・模型视图矩阵9四元数

•用四元数进行运算

・四元数9模型视图矩阵

______________________________J

四元数与旋转

•四元数q=(w,%,y,z)对应的旋转矩阵为

1-2/-2?2xy-2wz2xz+2wy0

2xy+2wzl-2x2-2z22yz~2wx0

M=

2xz-2wy2yz+2wxl-2x2-2y20

0001

矩阵到四元数的转换

MatToQuat(floatm[4][4]rQUAY,quat)£

floattr,s,q[4];

intifj,k;

intnxt[3]={1,2,0};

tr=m[0][0]+m[1][1]+

if(tr>0.0)<

s=sqrt(tr+1.0);

quat->w=s/2.0;

s=0.5/s;

quat->x=(m[l][2]-*5;

quat->y=(m[2][0]-m[0][2])*s;

quat->z=(m[0][l]-m[l][0})•s;

yelse(

j=0;

if(m[l][l]>m[0][0])i=1;

if(m[2][2]>m[i][i])i=2j

j=nxt[i];

k=nxt[j];

S=sqrt((m[i][i]-(inQjQ]+m[k][k]))+1.0);

q[i]=s,0.5;

if(s!=0.0)s=0.5/s;

q[3]=(m[j][k]-m[k][j])*s;

q[j]=+m[j][i])*s;

q[k]=(m£i][k]+m[k][i])•s;

quat->x=q[0];

四元数到矩阵的转换

QuatToMatrix(QUAT*quat,floatm[4][4]){

floatwx,wyzwz,xx,yy,yz,xy,xz,zz,x2,y2,z2;

x2=quat->x+quat->x;y2=quat->y+quat->y;

z2=quat->z+quat->z;

xx=quat->x♦x2;xy=quat->x♦y2;xz=quat->x*z2;

yy=quat->y*y2;yz=(|iiat->y*z2;zz=quat->z♦z2;

wx=quat->w*x2;wy=(|uat->w*y2;wz=quat->w*z2;

=1.0-(yy+zz);ni[l][0]=xy-wz;

=xz+wy;m[3][0]=0.0;

=xy+wz;m[l][l]=1.0-(xx+zz);

=yz-wx;m[3][l]=0.0;

=xz-wy;m[l][2]=yz+wx;

=1.0-(xx+yy);m[3][2]=0.0;

=0;in[l][3]=0;

=0;m[3][3]=1;

•交互计算机图形学的一个主要问题就是如

何应用二维的设备(如鼠标)控制三维的

对象

例如:如何构造一个实例矩阵?

•替代方式

虚拟跟踪球

三维输入设备,如:空间球(spaceball)

应用屏幕区域:根据不同的鼠标按钮状态,利

用到中心点的距离控制角度、位置、放缩

物理跟踪球

•跟踪球是一个底朝上的鼠标

•如果球和滚轴之间有小的摩擦力,我们可以推

动球使其模持滚动产生连续的变化

•两种可能的操作模式

连续推动或跟踪手的运动

旋转

_____________________7

鼠标模拟跟踪球

•问题:我们希望从鼠标得到两种行为模式

•我们用鼠标模拟无摩擦(理想)跟踪球

•一'旦开始旋转,就会一直旋转,除非强迫停止

•分两步解决:

•把跟踪球位置映射到鼠标位置

用GLUT得到恰当的模式

跟踪球的标架

原点在球心

X

投影跟踪球位置

•把球面上一点正交投影到y=0平面

Z

逆投影

•因为投影平面和上半球面都是二维曲面,

我们可以逆向投影

•y=0平面上一点(xQz)对应到半球面上的

点(x,y,z),这里

2_*2_2ifr>|x|>0,r>|z|>0

y=Jrxz

计算旋转

•假设我们从鼠标得到两个点

•可以把它们投影到半球面上的点P1和p2

•这两个点确定了球面上的一个大圆

•找到恰当的旋转轴和选择角度就可以把P1

旋转到p2

利用叉积确定旋转轴备餐喊

•旋转轴就是原点和Pl,P2这两个点所确定

平面的法向.

旋转角

•Pl和p2的夹角为

sin0|=———

IPi"P2I

•如果我们缓慢移动鼠标或者频繁采样鼠标

位置,那么。将很小,我们可用近似计算

公式

sin0«0

用GLUT实现

•我们用空闲、运动和鼠标回调函数实现虚

拟跟踪球

•用三个逻辑值来控制鼠标的动作

•trackingMouse:如果真〉更新跟踪球位

•redrawContinue:十口果真,空闲回调函数

发出刷新信号

•trackbalIMove:如果真,更新旋转矩阵

•在这个例子里,我们用虚拟跟踪球旋转之

前建模的彩色立方体

#defineboolint/*ifsystemdoesnotsupport

booltype*/

#definefalse0

#definetrue1

#defineM_PI3.14159/*ifnotinmath.h*/

intwinWidth,winHeight;

floatangle=0.0,axis[3],trans[3];

booltrackingMouse=false;

boolredrawContinue=false;

booltrackbalIMove=false;

floatlastPos[3]={0.0,0.0,0.0};

intcurx,cury;

_int_sta_rtX,_st2artY;_________7

Voidtrackball_ptov(int*,inty,intwidth,

intheight,floatv[3])

floatd,a;

/*projectx,yontoahemispherecentered

withinwidth,height,notezisuphere*/

v[0]=(2.0*x-width)/width;

v[1]=(height-2.0*y)/height;

d=sqrt(v[0]*v[0]+v[1]*v[1]);

v[2]=cos((M_PI/2.0)*((d<1.0)?d

:1.0));

a=1.0/sqrt(v[0]*v[0]+v[l]*v[l]+

v[2]*v[2]);

v[0]*=a;v[1]*=a;v[2]*=a;

glutMotionFunc(1)

voidmouseMotion(int*,inty)

{

floatcurPos[3]

dx,dy,dz;

/*computepositiononhemisphere*/

trackball_ptov(xAy,winWidth,winHeightAcurPos);

if(trackingMouse)

computethechangeinposition

onthehemisphere*/

dx=curPos[0]-lastPos[0];

dy=curPos[1]-lastPos[1];

dz=curPos[2]-lastPos[2];

glutMotionFunc(2)

if(dx||dy||dz)

/*computethetaandcrossproduct*/

angle=90.0*sqrt(dx*dx+dy*dy+dz*dz);

axis[0]=lastPos[1]*curPos[2]一

lastPos[2]*curPos[1];

axis[1]=lastPos[2]*curPos[0]一

lastPos[0]*curPos[2];

axis[2]=lastPos[0]*curPos[1]一

lastPos[1]*curPos[0];

/*updateposition*/

last

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论