计算机图形学-几何变换

计算机图形学中几何对象以及对象之间的关系可以用三种基本类型来描述:

  1. :空间中的一个位置,没有大小、形状
  2. 标量:实数、复数和有理函数,服从一组规则的对象。可以定义加法和乘法,满足交换律和结合律,有加法和乘法的逆元(隐含定义了减法和除法)。
  3. 向量:既有大小又有方向,在空间中没有固定位置,有相同的大小和方向的有向线段就是相同的向量。

标量场scalar field:标量组成的集合,标量集中任何两个标量都可以经过加法和乘法得到另一个标量,这两种运算满足封闭性。结合律。交换律和对逆元素的要求,构成了一个标量场。

线性空间(向量空间):包含向量和标量两种实体,包含两个标量之间的运算、标量-向量乘法sclar-vector multiplication(得到向量)和向量-向量加法vector-vector addition(得到向量)。

例子:实数n元组、有向线段等。

向量空间不一定要有度量。

Euclid space:向量空间的扩展,增加了对大小或距离的度量。

仿射空间affine space:向量空间的扩展,除标量和向量外还包含点。定义了向量-点加法(得到y一个点)。(又称点-点减法,得到一个向量。)

           没有定义两个点之间的加法和标量与点的乘法(但有一种仿射加法)。

Linearly independent:向量空间中,如果一组向量中的任何一个向量都不能由其他向量通过标量-向量乘法和向量-向量加法表示,则称这组向量是线性无关的。

Dimension:向量空间的维数是线性无关向量组中向量数目的最大值。

坐标系变换

exp:u1, u2, u3 –> v1, v2, v3

u=Mv

w=aTv=bTu

a=MTb

T=(MT)-1

b=Ta

 

齐次坐标:用于解决向量和点可能被搞混的问题。

  点与标量的“乘法”定义为:

    0·P=0

    1·P=P

  点和其他标量的乘法无意义。

  列向量表示点:最后一项为1

  列向量表示向量:最后一项为0。

齐次坐标对坐标系变换公式仍然适用。

从一个标架转换到新标架:通过三个向量u、v、n和新标架原点p在原来标架下的表示来指定新标架。

   a=Cb          C即为MT

   a为新标架坐标,b为原标架坐标

   a、 b是一个点或一个向量的齐次坐标表示。

  C=[u, v, n, p]-1 =   

 OpenGL绘制流水线涉及的标架顺序

  1. 对象坐标系或建模坐标系
  2. 世界坐标系
  3. 眼坐标系或照相机坐标地
  4. 裁剪坐标系
  5. 规范化的设备坐标系
  6. 窗口坐标系或屏幕坐标系

每次标架变换都对应一个仿射变换,OpenGL把从模型坐标到世界坐标以及从世界坐标到眼坐标的变换合并为模-视变换,对应的矩阵是模-视变换矩阵。模-视变换矩阵将点和向量在对象标架下的齐次坐标变换成眼标架下的表示。

模-视矩阵是系统状态的一部分,总是有一个当前的照相机标架和一个当前的对象标架,OpenGL提供矩阵栈用于将模-视变换矩阵保存起来。

初始默认的模-视矩阵:单位阵,此时对象标架和眼标架是重合的。

照相机位于眼标架的原点,照相机坐标系的三个基向量:

  1. 观察正向:y轴正方向。
  2. 正对方向:z轴负方向。
  3. 另一个正交方向:x轴,正方向应使得xyz构成右手系坐标。

只要改变当前的模-视变换矩阵,就可以在多个标架之间转换。

大多数情况下把照相机看做是固定的,其他标架则相对于照相机移动。

 举例:

多数应用将对象指定在原点附近,而照相机通常设置为只能对它前面的对象成像。为了生成图像包含全部对象,必须让照相机远离对象,或让对象远离照相机,即相对于对象标架移动照相机标架。

如果把照相机标架看成固定的,并且在照相机标架下通过模-视矩阵制定对象标架,

模-视变换矩阵

把对象标架下的点(x,y,z)变换成照相机标价下的点(x,y,z-d)。

世界标架可以相对于照相机标架移动,选择一个足够大的正数作为d,就可以把对象移动到照相机前面。

注意:用户建模时(如调用glVertex3f(x,y,z))使用的是世界坐标系,并且仍然像以前那样摆放对象。

对于大多数几何问题,通常是通过一系列旋转、平移缩放的几何变换实现从一个标架到另一个标架的变换。

仿射变换:将一个点(或向量)映射成另一个点(或向量)。

点的仿射变换有12个自由度,向量的放射变换有9个自由度。

线段或直线的放射变换有12个自由度。

旋转和平移都是刚体变换(rigid-body transformation),旋转和平移的任何组合都不能改变对象的形状和提及,只能改变对象的位置和方向。

缩放:一种仿射变换,但不是刚体变换。

变换级联

如果只变换一个点:

q=(C(B(Ap)))

如果变换多个点(流水线变换):

M=CBA

q=Mp

CTM:current transformation matrix,当前变换矩阵,是绘制流水线的一部分。

初始时被设置成4*4单位阵 CI

两种操作:将CTM直接设置为某个矩阵或用一个矩阵左乘或右乘CTM。(OpenGL没有提供左乘。)

平移、以原点为不动点的缩放和以原点为不动点的旋转:

CCT

CCS

CCR

 

或加载形式:

CT

CS

CR

多数系统允许把CTM直接设置成任意矩阵M或用任意矩阵M右乘CTM。

 OpenGL中,应用到所有图元的变换矩阵是模-视变换矩阵GL_MODELVIEW和投影变换矩阵GL_PROJECTION的乘积,也可以看做是CTM。

使用glMatrixMode选择想要的矩阵,然后单独对其进行设置或修改。

1 //将选定矩阵设置任意矩阵
2 
3 glLoadMatrixf(pointer_to_matrix);
4 
5 //将选定矩阵设置为单位阵
6 
7 glLoadIdentity();

旋转、平移、缩放矩阵函数,通过右乘改变选定的矩阵。

glRotate(angle, vx, vy, vz); //旋转角度,旋转轴的方向向量

glTranslatef(dx, dy, dz); //位移向量的三个分量

glScalef(sx, sy, sz); //沿着每个坐标轴的缩放因子

OpenGL中的规则:最后指定的变换最先被应用,所要求的函数调用以相反的顺序出现。

//将当前矩阵设置成一个4*4的齐次坐标矩阵

glLoadMatrixf(myarray);

  

//对当前矩阵右乘一个自定义的矩阵, myarray是把矩阵各列连起来的一维数组

glMultMatrixf(myarray);

如果右乘4*4矩阵m,可以生成myarray:

GLfloat m[4][4];

GLfloat myarray[16]’

for(i=0;i<3;i++)

           for(j=0;j<3lj++)

                     myarray[4*j+i]=m[i][j];

 另一种方法:

在应用实例变换前,利用glPushMatrix将当前矩阵压入栈中

glPushMatrix();

 glTranslatef(…);

glRotatef(…);

glScalef(…);

//出栈恢复

glPopMatrix();

原文地址:https://www.cnblogs.com/RDaneelOlivaw/p/6691051.html