三维图元的输出

从命令形式上看,在很多图形软件中,三维图元的输出只是在原来二维图元输出命令的基础上增加一个后缀3,如move3维形式的:move-3(x,y,z)line的三维形式为:dine-3(x,y,z)Polyline的三维形式为:polyline-3(n,x-array,y_array,z_array)。实际上,要在图形输出设备上输出一个三维图元,必须进行投影变换,为与前面所提供的投影变换相一致。我们假定其视域坐标系统(Viewig coordinate System简称VCS)定义为:投影面与xoy坐标而重合;z轴正向指间要表达的物体;透视投影的中心位于z轴的负轴之上。

要将三维图元输出到图形设备上,必须通过以下步骤:

1    定义一个视域坐标系统VCS,为此需指定如下数:

    ·VCS坐标原点,也称View reference pont;

    ·VCSz轴方向,也称view plane normal, xoy平面称为vierpin

    ·VCSy轴方向,又称view up vector

2将投影物体的世界坐标变换为视域坐标。在完成这两个前奏步骤之后,投影便可进行。然后,从二维视域坐标转换为NDC,便可在荧光屏上显示了。后两个步骤如下:

3选择平行投影或透视投影进行投影变换。使得VCS的三维对象变为VCS中在yox平面中的二维对象。

4在VCSyox平面中取一个窗口,并定义一个相应的视区,进行标准化变换。

上述4步构成本维图元输出的全过程,它是三个坐标系统,世界坐标、视域坐标、标准设备坐标的依次递变过程(316)。其中标准化变换和投影变换已在上两节中介绍过。下面介绍视域变换的过程。世界坐标WCS 视域变换  视域坐标VCS 投影  变换  标准化变换  标准设备坐标

  文本框: 图3.33 三维坐标变换全过程

 

    

()视域变换

    视域变换(view transformation)是将一个三维对象在世界坐标系统中的坐标转变为在视域坐标系统中的坐标过程。这一过程可以看成将WCS中的三个坐标轴转换为与VCS的三个坐标轴对应重合的逆变换。下面给出视域变换的一个统一步骤。

    将一个任意方向的VCS变换到与WCS重合的过程可由四步完成:1)将左手坐标改为右手坐标系统;2)原点重合;3)z轴重合;4)其余两轴重合。其中中间两步与绕任一轴旋转中的几个步骤相同。四步应完成的运算如下:

    VCS的坐标原点为(x0,y0,z0)z轴方向矢量为(xn,yn,zn)h轴方向矢量为(xu,yu,zu);图3.34(a)示出WCSVCS的原来情况。xv,yv,zvVCS的三根坐标轴;xw,yw,zwWCS的坐标轴。视域变换的过程是将xv,yv,zv变换到与xw,yw,zw三轴重合,这也就是将WCS中的物体坐标变换到VCS中去的过程。

    1左手系统改为右手系统的变换由zv轴改变方向而完成,(3.34(b))。变换矩阵为S(11,-1)

    2原点重合的变换是平移(3.34(c)),为T(x0,y0,-z0)

    3zv轴与zw轴重合的变换为先绕xw轴旋轴VCS α角,再绕yw旋转VCSβ角(3.34(d)(e)),运算矩阵为Rx(α)Ry(β)的变换矩阵参数值之求法见旋转变换公式的推导。

    4将VCSzw轴旋转γ角,使得VCS的三根轴与WCS三轴对应重合,变换矩阵为Rz(γ)。其中矩阵的参数求法如下:

    设经过上述变换,yw方向的矢量为(xuyuzu),它是单位矢量为u(au,bu,cu),其值可以由上述变换中得出。其中cu0,因为uywoxw的平面上。令ywyw轴之单位矢量:γ为yvyw之夹角(3.34(e)),故有:

cosγ= =bu

其中bu=

并有:u×ywzwu||yw|·sinγ

由矢量积的行列式运算,又得:

u×ywzw·au

并因为|u|·|yw|=1,因此有:

sinγ=au

其中,au

z轴γ角的变换矩阵为:

Rz(γ)

    综上所述,视域变换由下述级联矩阵变换实现:

       p′=p·s(1,1,-1)·T(x0,y0,z0)·Rx(α)·Ry(θ)·Rz(γ)

其中,p是变换前物体上的三维齐次坐标;

      p′是变换后物体上的三维齐次坐标。

 

文本框: 图3.34  视域变换的过程

 

 

    ()定义三维视域命令

    在图形软件的使用中,三维物体显示所需的三级变换:视域变换、投影变换、标准化变换都由图形软件自动完成,但用户必须指定三级变换所需的参数。下面两条指令用定义三维对象的三级变换的参数:

    1定义视域变换参数:

    Creat_view_maatrix(x0,y0,z0,xn,yn,zn,xu,yu,zu,view_matrix)

其中,x0,y0,z0VCS的原点坐标;

      xn,yn,znVCSz轴正向矢量;

      xu,yu,zuVCSy轴正向矢量;

      view_matrix是输出的视域变换矩阵。

这条指令完成如下上节所述的功能:

    view_matrixS(1,1,-1)·T(x0,y0,z0)·Rx(α)·Ry(θ)·Rz(γ)

    2定义投影和标准化变换的参数:

    Set_view_representation(view_index,view_matrix,projection_type,xp,yp,zp,Xw-min,Xw-max,Yw-min,Yw-max,near,far,Xv-min,Xv-max,Yv-max)

其中,view_index是该变换的编号;

    view_matrix是所输入的视域变换矩阵;

    projection_type是投影类型(透视,或平行)的选择;

    xp,yp,zp对于平行投影,它们表示投影线的方向矢量;对于透视投影,它们表示投影中心的位置;

    Xw-min,Xw-max,Yw-min,Yw-max,near, far是表示窗口的大小和前(near)(far)的深度范围;

Xv-min,Xv-max,Yv-min,Yv-max是视区的大小。

    上面两条指令定义了编号为view_index视域的详细特征。在这之后,用户便可使用下面的指令来选择视域。

    3Set_view_index(vi)

    其中vi是已经定义了的视域的编码。

    程序3.1给出了Creat_view_matrix指令的实现全过程。

##includestdio.h

##includemath.h

#define MAX      10

 

struct pointtype

                 float x;

                 float y;

                 float z;

                 };

#define POINT struct pointtype;

 

POINT pointMAX];

 

Creat_view_matrix(x0,y0,z0,xn,yn,zn,xu,yu,zu,p1)

float x0,y0,z0;

float xn,yn,zn;

float xu,yu,zu;

float pf14][4];

{

              float a, b, c, d, r, r1;

              float sin1, cos1, sin2, cos2, sin3, cos3;

              float trans14][4],trans24][4],p24][4];

              int i, j;

              POINT point;

/*---------------------Move transformation----------------------*/

              for(i=0;i4i++)

                  for(j=0;j4j++)

                  trans1i][j]=(i==j)

 

              trans10][0]=1

              trans10][0]=1

              trans12][2]=1

              trans13][3]=1

              trans10][3]=-x0

              trans11][3]=-y0

              trans12][3]=-z0

 

 

              xn-=x0

              yn-=y0

              zn-=z0

/*------------------------From right_hand to left_hand-----------*/

              for(i=0;i4i++)

                  for(j=0;j4j++)

                  trans2i][j]=(i==j)

 

              trans20][0]=1

              trans21][1]=1

              trans22][2]=-1

              trans23][3]=1

 

 

              zn=-zn

              accumulate_matrix(trans1,trans2,p1)

/*-----------------------Transformtion around X-------------------*/

              rsqrt(xn*xnyn*ynzn*zn)

              axn/r

              byn/r

              czn/r

              dsqrt(b*bc*c)

              sin1b/d

              cos1c/d

              sin2=-a

              cos2d

 

 

              for(i=0;i4i++)

                  for(j=0;j4j++)

                  trans1i][j]=(i==j)

 

              trans10][0]=1

              trans10][0]=cos1

              trans12][1]=sin1

              trans11][2]=-sin1

              trans12][2]=cos1

              trans13][3]=1

              trans12][3]=-z0

 

              accumulate_matrix(p1,trans1,p1);

*/----------------------Transformation around Y----------*/

             

              for(i=0;i4i++)

                  for(j=0;j4j++)

                  trans1i][j]=(i==j)

 

              trans10][0]=cos2

              trans12][0]=-sin2

              trans11][1]=1

              trans10][2]=sin2

              trans12][2]=cos2

              trans13][3]=1

 

              accumulate_matrix(p1,trans1,p1)

*/---------------------------Transformtion around Z--------------*/

              point.xxu

              point.yyu;

              point.zzu

              realize_trans(p1,&point);

              xupoint.x;

              yupoint.y;

              zupoint.z;

              r1sqrt(xu*xuyu*yu);

              sin3xu/r1;

              cos3yu/r1;

 

 

              for(i=0;i4i++)

                  for(j=0;j4j++)

                  trans1i][j]=(i==j)

 

              trans10][0]=cos3

              trans11][0]=sin3

              trans10][1]=-sin3

              trans11][1]=cos3

              trans12][2]=1

              trans13][3]=1

 

              accumulate_matrix(p1,trans1,p1);

              realize_trans(m,p)

 

 

 

realize_trans(m,p)

 POINT *p;

 float m4][4];

              float x,y,z;

                 x=(m[0][0]p->xm1][0*p->ym[2][0]*p

->zm3][0)

                 y=(m[0][1]p->xm1][1*p->ym[2][1*p

->zm3][1)

                 z=(m[0][2]p->xm1][2*p->ym[2][2*p

->zm3][2)

                 p->xx

                 p->yy

                 p->zz

 

accumulate_matrix(m1,m2,m3)

float m14][4],m24][4,m34][4;

                  flaot m[4][4];

                  int i,j,k;

 

              for(i=0;i4i++)

                  for(j=0;j4j++)

                  mi][j]=m1i][j];

 

              for(i=0;i4i++)

                  for(j=0;j4j++)

                     m3i][j]=0

                     for(k=0,k4k++)

                       m3i][j]+=mk][j*m2i][k;

                    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值