第 8章 图形变换
? 在计算机图形系统中, 经常需要对基本图形进
行变换, 例如:平移, 旋转, 放缩, 对称和投
影等 。 一幅基本的图形包含两组信息, 一组是
图形的几何信息, 如图形的顶点坐标, 另一组
是图形的拓扑信息, 即图形各顶点之间的关系 。
图形的几何变换是指图形的几何信息发生改变,
而拓扑关系不变 。 所以, 图形的几何变换只考
虑图形各顶点坐标的变换 。 图形变换分为两种,
一种是图形不变, 而坐标系发生变化, 另一种
是坐标系不变, 而图形位置和形状发生变化 。
后一种情况是本章讲解的重点, 分为二维图形
几何变换, 三维几何变换和投影变换等 。
8,1 坐标系和坐标变换
?8,1,1坐标系
?对图形对象的描述, 图形的输入输出,
都是在一定的坐标系中进行的 。 常用的
坐标系分为用户坐标系, 设备坐标系和
规格化的坐标系三种 。 不同的坐标系有
不同的坐标原点和坐标刻度, 其取值范
围及适用的对象也有所不同 。
?在几何学中, 为了用数字描述空间的物
体, 包括物体的大小, 形状和位置, 必
须引进笛卡尔坐标系 。 用户总是习惯于
在自己熟悉的坐标系中描述客体或绘制
图形, 这个用户定义客体的坐标系, 称
为用户坐标系, 或称为客体坐标系 。 常
用的用户坐标系有直角坐标系, 极坐标
系, 对数坐标系, 球形坐标系等 。 在图
形系统中, 一般只用到直角坐标系 。 直
角坐标系又称为宇宙坐标系, 可以分为
二维直角坐标系合三维直角坐标系 。
? 设备坐标系一般是二维坐标系, 图形的输出在
设备坐标系中进行 。 设备坐标系包括有:绘图
仪坐标系和显示屏幕坐标系 。
? 规格化坐标系是与设备无关的坐标系, 用来构
造与设备无关的图形系统 。 通常取无量纲的单
位长度作为在规格化坐标系中图形输入输出的
有效空间, x和 y方向的取值范围为 [0,1]。
用户坐标系、规格化坐标系和设备坐标系
三者之间的关系如图 8.1所示。
? 图 8.1 三种坐标系之间的关系
Y Y
Y
Y
X X
X
X
(Xw,Yw )
Hw
Ww(Xlw,Ybw)
1
1
(Xn,Yn )
用户坐标系 规格化坐标系 设备坐标系
规格化变换
或者
(0,0)
8,1,2 窗口与视口
?1,用户域和窗口
?用户用来定义设计对象的实数域称为用
户域, 也称为用户空间 。 人们所要描述
的图形均在用户域中进行定义 。 从理论
上说, 用户域是连续的, 无限的 。
?用户域中定义的对象可能很大, 很复杂,
用户可以指定其中感兴趣部分区域通过
屏幕显示出来, 通常称这个区域为窗口 。
就像人们站在房间里通过窗口往外看,
只能看到窗口范围内的景物, 人们选择
不同的窗口可以看到不同的景物 。 窗口
区一般是矩形区域, 可以用其左下角和
右上角的坐标来表示 。 窗口可以嵌套,
即在第一层窗口中可以再定义第二层窗
口 。 在某些情况下, 还可以定义圆形窗
口或多边形窗口 。
2.屏幕域和视图区
? 图形设备上用来输出图形的最大区域称为屏幕
域, 即显示器的显示区域, 它是有限的整数域,
用 显 示 器 分 辨 率 来 表 示, 如 640X480、
1024X768等 。
? 在计算机屏幕上, 一般的图形系统常常包含菜
单区, 工具栏, 图形显示区, 信息提示区等,
图形只是在图形显示区显示, 而不是在整个屏
幕上显示 。 我们把任何小于或等于屏幕域的区
域称为视图区 。 视图区由用户在屏幕域中用设
备坐标定义, 一般定义为矩形, 由其左下角坐
标和右上角坐标来定义 。 在一个计算机屏幕上,
可以定义多个视图区, 分别显示不同的图形 。
8,1,3 坐标变换
?由于窗口是在用户域中定义的, 而视图定
义在计算机屏幕上, 如果要将用户域中窗
口内的景物在计算机屏幕的视图中显示出
来, 就必须求出图形在窗口区和视图区之
间的转换关系, 这就是窗口与视图之间的
坐标变换 。
?设矩形窗口的左下角坐标为( WXL,WYB),
右上角坐标为( WXR,WYT)。 在计算机屏
幕上定义的视图区的左下角坐标为
( VXL,VYB),右上角坐标为( VXR,VYT)。
如图 8-2所示,则在窗口区内的一点( Xw,Yw)
与视图区中的对应的一点( XV,YV) 存在如下
的转换关系:
图 8-1 窗口区与视图区的对应关系
(式 8-1-1)
若令:
a=( VXR-VXL)/( WXR-WXL)
b= VXL - WXL,( VXR-VXL)/( WXR-WXL)
c=( VYT-VYB)/( WYT-WYB)
d= VYB - WYB,( VYT-VYB)/( WYT-WYB)
则式 8-1-1可以简化为:
XV = a,Xw +b
YV =c,Yw +d (式 8-1-2)
?其中,a和 c分别反映了视图区和窗口区
之间在 x和 y方向上的伸缩比,b和 d则分
别反映了定位点在 x和 y方向上的偏移量。
显然,如果 a=c=1,b=d=0,则表示窗口
区和视图区的大小相等。若 a≠ c,则图
形会发生畸变。例如,在窗口区内的一
个圆,在视图区中则显示为一个椭圆。
因此,应当采取措施加以避免。
8,2 二维图形的几何变换
?二维图形的几何变换是指在不改变图形
连线次序的情况下,对一个平面点集进
行线性变换。对于线框图的变换,把图
形的一系列顶点作几何变换后,连接新
的顶点系列,即可产生出变换后的新图
形。图形变换分两种情况,一是图形的
相对位置发生改变,如平移、旋转和对
称变换,另一种是图形的形状发生变化,
如图形的缩放、错切或压缩变换。
8.2.1 二维图形几何变换的数
学表示
?1,二维图形几何变换的一般表示
?在二维空间中, 可以用一个行向量 [x,y]或
一个列向量 来表示一个点的坐标 。 二
维图形是一个平面点集 M,可以用 NX2矩
阵来表示, 其中 N为定点数, 矩阵 M表示
如下:
? M= ( 式 8-2-1)
x
y
x1 y1
x2 y2
.,
.,
.,
xn yn
? 设 P=[xi yi]为图形上的任意一点的坐标,
P’=[ xi ’ yi’]表示 P点经某种变换后新位置的坐
标 。 对于二维变换, 一般分为下面三种情况:
? ( 1) 对于平移变换, 设 Tx为点 P沿 X方向的平
移量, Ty为沿 Y方向的平移量, 则有:
? xi ’= xi + Tx
? yi ’= yi + Ty ( 式 8-2-2)
? Tx 和 Ty 是平移量,有正负之分。当平移方
向与 X轴一致时,Tx值为正,否则 Tx值为负;
当平移方向与 Y轴一致时,Ty值为正,否则 Ty
值为负;如图 8-2-1所示。
?(2)对于比例变换 ( 放缩 ), 则是给定 P
点相对于坐标原点沿 X方向的比例系数 Sx
和沿 Y方向的比例系数 Sy,经变换后, 则
有:
? xi ’= Sx, xi
?yi ’= Sy, yi ( 式 8-2-3)
?当 Sx = Sy <1时, 图形缩小;
?当 Sx = Sy =1时, 图形不变;
?当 Sx = Sy >1时, 图形放大;
?当 Sx ≠ Sy 时, 图形发生畸变;不考虑
这种情况 。
如图 8-2-2所示。注意图形放大或缩小时,
图形位置都发生了变化。
Tx
Ty
y
x
图 8-2-1 平移变换
Sx = Sy
<1
Sx = Sy >1
y
x
图 8-2-2 比例变换
Sx = Sy =1
? 3) 对于旋转变换, 先讨论平面上点绕坐标原
点的旋转变换 。
? 一个平面图形绕坐标原点逆时针旋转 θ 角
度, 图形的形状保持不变, 但图形各顶点的位
置坐标相应地发生了改变 。 如图 8-2-3所示, 可
以得到旋转后的坐标 。
? 图 8-2-3 旋转变换
? 设 A(x,y)绕原点逆时针旋转 θ 角度后, 新位置
的坐标为 A’(x’,y’),旋转半径 R=OA=OA’
? 因为:
A(x,y)
y
x
图 8-2-3 旋转变换
C
A’(x’,y’)
B
C’
B’
αθO
? Cosα =x/R,Sinα =y/R
? x’=RCos(θ +α )
? =R(Cosθ Cosα -Sinθ Sinα )
? =xCosθ -ySinθ
? y’=RSin(θ +α )
? =R(Sinθ Cosα +Cosθ Sinα )
? =xSinθ +yCosθ
? 即:
? x’= xCosθ -ySinθ
? y’=xSinθ +yCosθ ( 式 8-2-4)
? 注:( 1)式 8-2-4是绕原点旋转;
? ( 2)逆时针旋转,θ 角度为正。
2.二维图形几何变换的齐次
坐标表示
?对于上述常用的二维几何变换, 我们希
望用一种统一的矩阵方式来表示, 这就
需要用齐次坐标来表示 。
? 所谓齐次坐标表示法就是用 n+1维向量
表示一个 n维向量 。 在 n维空间中, 点的
位置矢量具有 n 个坐标分量
( P1,P2,…,Pn), 且是唯一的 。 若用齐
次坐标表示时, 此向量有 n+1个坐标分量
( hP1,hP2,…,hPn,h),且不唯一 。
?二维齐次坐标的一般表示形式为 [hX,hY,h]。
当 h=1 时, 二维坐标点的齐次坐标为
[x,y,1]; 当 h=2时, 二维坐标点的齐次坐
标为 [2x,2y,2]。 例如, [2,3,1],[2,6,
2],[6,9,3]都表示二维空间的点 [2,3]。
所以, 只有当 h=1时, 二维点的齐次坐标
中的 x,y数值才与二维坐标中点的位置矢
量的 x,y值相等 。
?若已知一个其次坐标形式为 [hX,hY,h],则
位置矢量
? x=hX/h,y=hY/h
? 我们可以用齐次坐标表示法 P=[x,y,1]来代表二
维平面内的一个点, 用 3X3矩阵表示变换矩阵 。
若令变换矩阵 a b p
? T= c d q
? l m s
? 则, 点 P经矩阵 T作用后得到
? [X Y H]=[x y 1]
? =[ax+cy+l bx+dy+m px+qy+s]
? 从而可以求出变换后点 P’的二维直角坐标为:
? x’=X/H = ( ax+cy+l)/( px+qy+s)
? y’=Y/H= (bx+dy+m)/( px+qy+s)
? 上述过程, 称为齐次坐标的正常化 。
a b p
c d q
l m s
8.2.2 基本的二维图形几何变
换
? 1,平移变换
? 在变换矩阵中, 取 l=Tx,m=Ty,l和 m分别表
示点 P(x,y)沿 X,Y方向的平移量 。 则平移变换可
以表示为,P’=P.T,其中平移矩阵
? T= 1 0 0
? 0 1 0
? Tx Ty 1 ( 式 8-2-5)
? 1 0 0
? 即 P’=P.T=[x y 1] 0 1 0 =[x + Tx y + Ty 1]
? Tx Ty 1
? 因齐次坐标中的 h=1,规范化后得到
?
? x’=x + Tx
? y’= y + Ty
?与式 8-2-2一致 。 说明可以采用上述平移矩阵来对平面图形进
行平移变换 。 对于一个平面点集矩阵 M,如式 8-2-1所示, 可
以通过矩阵运算来得到变换后所有顶点的新位置坐标 M’。?
?
M’=M.T= = =?
?如果点 P(x,y)经 T1变换后平移了 ( Tx1,Ty1), 然后再经 T2
变换后又平移了 ( Tx2,Ty2), 那么将产生什么结果呢? 从
直观上, 应该是平移了 ( Tx1+ Tx2,Ty1+ Ty2), 那么用齐
次坐标表示应如何描述呢? 首先令?
P’=P? T1?
P’’=P’? T2=P? T1? T2
x1 y1 1
x2 y2 1
.,,
.,,
.,,
xn yn 1
1 0 0
0 1 0
Tx Ty 1
x1 + Tx y1 + Ty 1
x2 + Tx y2 + Ty 1
.,,
.,,
.,,
xn + Tx yn + Ty 1
x1’ y1’ 1
x2’ y2’ 1
.,,
.,,
.,,
xn’ yn’ 1
?其中,
?
?
?这确实说明了实际的平移量是 ( Tx1 + Tx2,
Ty1 + Ty2), 也就是说, 连续的平移变换
是平移量相加 。 在齐次坐标表示中, 可
用矩阵相乘来描述 。
? 2,比例变换
? 在变换矩阵 T中, 取 a=Sx,d=Sy,它们分别表
示点 P(x,y)沿 X和 Y方向相对原点的比例变换系
数, 比例变换矩阵 T为:
? T = Sx 0 0
? 0 Sy 0
? 0 0 1
? ( 式 8-2-6)
? 则比例变换可表示为:
? P’=P?T =[x y 1] Sx 0 0
0 Sy 0 = [x Sx y Sy 1 ]
0 0 1
?
?齐次坐标规范化后得
? x’= x Sx
? y’= y Sy
?此式与式 8-2-3相一致。这说明比例变换
可以用比例变换矩阵乘法来处理。
?连续的比例变换可以通过连续的矩阵乘
法来实现 。 例如, 点 P(x,y)经比例变换
T1(Sx1,Sy1)后, 再经比例变换 T2(Sx2,
Sy2),那么, 最终的比例变换矩阵
? 比例变换矩阵的另一种形式是:
? T = 1 0 0
? 0 1 0
? 0 0 s ( 式 8-2-7)
? 比例变换可表示为:
? P’=P?T =[x y 1] 1 0 0
? 0 1 0 =[x y s]
? 0 0 s
? 规范化后得到:
?
? 说明式 8-2-7是一个等比例变换, s是比例变换
系数 。 当 s>1时, 图形缩小;当 s=1时, 图形大
小不便;当 s<1时, 图形放大;
? 3,旋转变换
? 旋转变换矩阵为:
? T= cosθ sinθ 0
? - sinθ cosθ 0
? 0 0 1 (式 8-2-8)
? 其中, θ角度由正负之分, 即点 P在 XY平面的
内绕原点逆时针旋转所形成的角度为正, 反之
为负 。
? P’=P?T =[x y 1] cosθ sinθ 0
? - sinθ cosθ 0
? 0 0 1
? =[ xCosθ-ySinθ xSinθ+yCosθ 1]
? 规范化后得到:
? x’= xCosθ-ySinθ
? y’= xSinθ+yCosθ
? 与式 8-2-4相一致 。
? 两个连续的旋转变换应该是角度的相加 。 设点 P(x,y)经
旋转变换 T1(θ1角度 )后, 再经旋转变换 T2 (θ1角度 ),那
么, 最终的旋转变换矩阵
? T= T1? T2 = cosθ2 sinθ2 0 cosθ1 sinθ1 0
? - sinθ2 cosθ2 0 - sinθ1 cosθ1 0
? 0 0 1 0 0 1
? cosθ1 cosθ2-sinθ1 sinθ2 cosθ1 sinθ2+ sinθ1cosθ2 0
= - sinθ1 cosθ2-cosθ1 sinθ2 - sinθ1 sinθ2+ cosθ1cosθ2 0
0 0 1
?
= Cos(θ1+θ2) sin(θ1+θ2) 0
? - sin(θ1+θ2) cos(θ1+θ2) 0
? 0 0 1
?
?
? 4,对称变换
? 对称变换也称为反射变换或镜像变换 。
? ( 1) 对称于 Y轴
? 如图 8-2-4( a) 所示 。 P(x,y)点对称于 Y轴
的点 P’(x’,y’)应该满足条件:
? x’= -x
? y’= y
? 对称于 Y轴的变换矩阵:
? - 1 0 0
? TY = 0 1 0 ( 式 8-2-9)
? 0 0 1
? 对称于 Y轴的变换
? P’=P? TY =[x y 1] - 1 0 0
? 0 1 0 = [ -x y 1]
? 0 0 1
? 即可得到,x’= -x,y’= y 。
? ( 2) 对称于 X轴
? 如图 8-2-4( b) 所示 。 P(x,y)点对称于 X轴
的点 P’(x’,y’)应该满足条件:
? x’= x
? y’= -y
? 对称于 X轴的变换矩阵:
? TX = 1 0 0
? 0 - 1 0 ( 式 8-2-10)
? 0 0 1
? 对称于 Y轴的变换
? P’=P? TX =[x y 1] 1 0 0
? 0 -1 0 = [ x -y 1]
? 0 0 1
? 即可得到,x’= x,y’= - y 。
? ( 3) 对称于原点 O
? 如图 8-2-4( c) 所示 。 P(x,y)点对称于原点
O的点 P’(x’,y’)应该满足条件:
? x’= -x
? y’= -y
? 对称于 X轴的变换矩阵:
? To = - 1 0 0
? 0 - 1 0
? 0 0 1 ( 式 8-2-11)
? 对称于 Y轴的变换
? P’=P? To =[x y 1] - 1 0 0
? 0 -1 0
? 0 0 1 = [ -x -y 1]
? 即可得到,x’= -x,y’= - y 。
? ( 4) 对称于直线 y=x
? 如图 8-2-4( d) 所示 。 P(x,y)点对称于直线
y=x的点 P’(x’,y’)应该满足条件:
? x’= y
? y’= x
? 对称于 X轴的变换矩阵:
? Ty=x = 0 1 0
? 1 0 0
? 0 0 1 ( 式 8-2-12)
? 对称于 Y轴的变换
? P’=P? Ty=x =[x y 1] 0 1 0
? 1 0 0
? 0 0 1 = [ y x 1]
? 即可得到,x’= y,y’= x 。
? ( 5) 对称于直线 y=-x
? 如图 8-2-4( e) 所示 。 P(x,y)点对称于直线
y=-x的点 P’(x’,y’)应该满足条件:
? x’= -y
? y’= -x
? 对称于 X轴的变换矩阵:
Ty =-x = 0 - 1 0
? - 1 0 0
? 0 0 1 ( 式 8-2-11)
? 对称于 Y轴的变换
P’=P? Ty =-x =[x y 1] - 1 0 0
? 0 -1 0 = [ -x -y 1]
? 0 0 1
? 即可得到,x’= -x,y’= - y 。
图 8-2-4 二维图形的对称变换
? 5,错切变换
? 错切变换也称为剪切, 错位或错移变换 。
? ( 1) 沿 x轴方向关于 y的错切
? 变换矩阵
Ty->x= 1 0 0
? c 1 0 (式 8-2-12)
? 0 0 1
? 点 P(x,y)经 Ty->x作用后, 得到的 P’(x’,y’)。
? P’=P? Ty->x =[x y 1] 1 0 0
? c 1 0 = [x+cy y 1]
? 0 0 1
? 即 x’=x+cy
? y’=y
? 说明变换前和变换后 y值坐标保持不变, 而 x坐
标依赖于初始坐标值 ( x,y) 及参数 c的值呈线
性变化 。 图 8-2-5说明了矩形 ABCD经 Ty->x矩阵
错切后变为一个平行四边形, 并且 c=tgα, 如
果 c>0,则沿 +x方向错切;若 c<0,则沿 -x方向
错切 。
? 图 8-2-5沿 x轴方向关于 y的错切变换
?
? ( 2) 沿 y轴方向关于 x的错切
? 变换矩阵
Tx->y= 1 b 0
? 0 1 0 (式 8-2-12)
? 0 0 1
? 点 P(x,y)经 Tx->y作用后, 得到的 P’(x’,y’)。
? P’=P? Tx->y =[x y 1] 1 b 0
? 0 1 0 = [x y+bx 1]
? 0 0 1
?
? 即 x’=x
? y’=y + bx
? 说明变换前和变换后 x值坐标保持不变, 而 y坐
标与初始坐标值 ( x,y) 及参数 b有关 。 图 8-2-
6说明了矩形 ABCD经 Tx->y矩阵错切后变为一个平
行四边形, 并且 b=tgβ, 如果 b>0,则沿 +y方向
错切;若 b<0,则沿 -y方向错切 。
? 图 8-2-6沿 y轴方向关于 x的错切变换
?
8.2.3 组合变换
? 在上一节中, 可以将二维图形的变换矩阵写成
如下形式:
? 由虚线分成四个部分, 各部分的功能如下:
? ( 1) a b
? c d 实现图形的比例变换, 对称变换,
旋转变换和错切变换;
? ( 2) [l,m] 实现平移变换, l和 m分别为 x,y方
向的平移量, 有正, 负值之分;
? ( 3) [s] 使图形产生等比例的变换 。 s>1,图
形缩小; s=1,图形不变; 0<s<1,图形放大;
? ( 4) p
? q 的用在其它变换中, 这里不做讨论 。
? 在实际的图形系统应用中, 一个复杂的变换往
往是由多个基本变换组合产生的, 这就提出了
如何进行组合变换的问题 。 所谓二维图形的组
合变换, 就是指在 XY平面内, 对一个已定义
的图形, 按照一定的顺序进行多次变换而得到
的新图形 。 通常, 我们总是试图将一些复杂的
变换转换成多个基本的变换, 一步一步变换来
实现 。 分步变换可以用基本的变换矩阵连乘来
实现, 表示总体变换的效果 。 可用下面的式子
来表示:
? T=T1XT2X???XTn
?其中, T1,T2???Tn为每一步的基本变换
矩阵 。 在数学中, 我们知道矩阵乘法不
满足交换率, 即设 A,B是两个矩阵, 则
存在下面关系:
? A X B ≠ B X A
?因此,组合变换中的顺序是不能颠倒的。
下面通过两个示例来介绍组合变换。
?例 1:图形绕任意点 P0(x0,y0)旋转 θ 角度
的变换矩阵 。
?解:前面我们介绍的绕坐标原点旋转的
变换矩阵, 为了实现题意要求, 可以分
解为以下三步来实现, 如图 8-2-7所示 。
?
?第一步:将原图形 Ⅰ 中的旋转点 P0平移
到坐标原点, 得到图形 Ⅱ, 变换矩阵为
T1= 1 0 0
? 0 1 0
? - x0 - y0 1
?第二步:图形 Ⅱ 绕坐标原点 o旋转 θ 角度,
得到图形 Ⅲ,变换矩阵为
?
T2= cosθ sinθ 0
? -sinθ cosθ 0
? 0 0 1
? 第三步:将图形 Ⅲ 中对应旋转点平移到原来的
位置 P0,得到图形 Ⅳ, 变换矩阵为
? 1 0 0
? T3= 0 1 0
? x0 y0 1
? 因此,组合变换矩阵为,
1 0 0 cosθ sinθ 0 1 0 0
? T= T1X T2X T3 = 0 1 0 -sinθ cosθ 0 0 1 0
x0 y0 1 0 0 1 - x0 - y0 1
? cosθ sinθ 0
? = -sinθ cosθ 0
? x0 (1- cosθ ) + y0sinθ x0sinθ + y0(1- cosθ ) 1
?如果上图中的原图形为长方形, A(20,10),
B(50,10),C(50,30),D(20,30),要求长
方形绕 A点作逆时针方向旋转 30°, 求变
换后各顶点的坐标 。
?原图形长方形点集矩阵表示为:
? 20 10 1
?P = 50 10 1
? 50 30 1
? 20 30 1
?
?变换后长方形的各顶点坐标为:
?
? 通过组合变换矩阵直接计算出
A’(20,10),B’(45.98,25),
C’(35.98,43.32),D’(10,27.32),绘出变
换后的最终图形, 中间的变换过程不必
一一计算出来 。
? 例 2:如图 8-2-8所示的矩形 ABCD,要变换成
A’B’C’D’,要求 DA=D’A’,AB=2A’B’,写出
该过程的组合变换的变换矩阵 。
? 解:
? ( 1) 将矩形 ABCD( Ⅰ ) 平移 ( -5,-5), 让
A点与坐标原点 O重合, 得到图形 Ⅱ, 变换矩
阵为:
? 1 0 0
? T1= 0 1 0
? -5 -5 1
? (2) 将图形 Ⅱ 绕原点 O逆时针旋转 90°, 得到
图形 Ⅲ, 变换矩阵为:
? Cos90 sin90 0 0 1 0
? T2= -sin90 cos90 0 = -1 0 0
? 0 0 1 0 0 1
? ( 3) 将图形 Ⅲ 在 Y方向上缩小一半, 得到图形
Ⅳ, 变换矩阵为:
? 1 0 0
? T3= 0 0.5 0
? 0 0 1
? 注意:比例变换是相对于原点 O的, 因此, 不
能将图形 Ⅲ 移到原位后再缩小 。 请读者思考 。
? ( 4) 平移图形 Ⅳ, 使图形 Ⅳ 左下角移到 ( 5,5)
位置, 与原图形的 A点重合, 得到图形 Ⅴ 。 平
移量应该为 ( 8,5), 所以变换矩阵为:
?
? 1 0 0
? T4= 0 1 0
? 8 5 1
? 因此, 组合变换矩阵表示为:
? 这样, 组合变换后图形的顶点坐标计算如下:
?
?
8,3 三维图形的几何变换
? 在三维空间中, 我们也采用齐次坐标技术来描
述空间的各点坐标和各种变换 。 空间点 P(x,y,z)
的齐次坐标表示为 [x y z 1],变换矩阵 T用
4X4矩阵来表示 。
? 从功能上分为四个子矩阵:
? a b c
? ( 1) d e f
? g h i, 可以产生比例、对称、旋转、
? 等基本变换;
?( 2) [l m n], 产生平移变换;
? p
?( 3) q, 产生透视投影变换;
? r
? ( 4) [s], 产生整体的比例变换;
?三维几何变换与上一节中介绍的二维几
何变换相同, 只不过三维空间的几何变
换比较复杂 。 从工程设计角度看, 三维
空间的几何变换直接与显示, 造型有关,
因此更重要一些 。
8.3.1 基本变换
? 1,比例变换
? ( 1) 局部变比
? 变换矩阵为:
? a 0 0 0
? T = 0 e 0 0
? 0 0 i 0
? 0 0 0 1
? 空间点 P(x,y,z)经变换后得到的坐标表示为:
? P’=P?T=[x y z 1] ?T=[ax ey iz 1]
? 其中, a,e,i分别为 x,y,z三个方向的缩放
系数 。
?( 2) 整体变比
?变换矩阵为:
? 1 0 0 0
? T = 0 1 0 0
? 0 0 1 0
? 0 0 0 s
? 规范化空间点 P(x,y,z)经变换后得到的坐
标表示为:
? P’=P?T=[x y z 1] ?T=[x y z s]
[x/s y/s z/s 1]
?即 x’=x/s,y’=y/s,z’=z/s。
? 2,平移变换
变换矩阵为:
? 1 0 0 0
? T = 0 1 0 0
? 0 0 1 0
? l m n 1
? P’=P?T=[x y z 1] ?T=[x+ l y+m z+n 1]
? 即 x’= x+l
? y’= y+m
? z’= z+n
? 其中, l,m,n分别是 x,y,z三个方向的位移
量, 并且位移量有正负之分, 与 x,y,z方向
一致的位移量为正, 否则为负 。
? 3,对称变换
? 三维图形的对称变换包括对坐标原点, 坐标轴
和坐标平面三种对称变换 。 这里主要讨论对坐
标平面的对称变换 。
? ( 1) 相对于 XY平面的对称变换
? 三维空间点 P( x,y,z) 相对于 XY平面的对称点
P’,x,y坐标不变, z坐标取反 。 如图 8-3-1所
示 。 所以, 变换矩阵为:
? 1 0 0 0
? Txoy= 0 1 0 0
? 0 0 -1 0
? 0 0 0 1
? P’=P?T=[x y z 1] ?T=[x y -z 1]
? 即 x’ = x, y’ = y, z’ = - z
?( 2) 相对于 XZ平面的对称变换
?三维空间点 P( x,y,z) 相对于 XZ平面的
对称点 P’,x,z坐标不变, y坐标取反 。
变换矩阵为:
? 1 0 0 0
? Txoz= 0 -1 0 0
? 0 0 1 0
? 0 0 0 1
? P’=P?T=[x y z 1] ?T=[x -y z 1]
?即 x’ = x, y’ = - y, z’ = z
O x
z
y
P(x,y,z)
图 8-3-1 三维空间对称变换
?( 3) 相对于 YZ平面的对称变换
?三维空间点 P( x,y,z) 相对于 YZ平面的
对称点 P’,y,z坐标不变, x坐标取反 。
变换矩阵为:
? -1 0 0 0
?Tyoz= 0 1 0 0
? 0 0 1 0
? 0 0 0 1
? P’=P?T=[x y z 1] ?T=[- x y z 1]
?即 x’ = - x, y’ = y, z’ = z
?4,旋转变换
? 在三维空间中, 基本旋转变换是指空
间立体绕坐标轴旋转一定的角度, 各旋
转角度的正方向如图 8-3-2所示 。
O x
z
y
图 8-3-2 三维空间旋转变换
? ( 1) 绕 x轴旋转 θ 角度
? x坐标不变, y,z坐标发生变化 。
? 变换矩阵为:
? 1 0 0 0
? Tx = 0 cosθ sinθ 0
? 0 - sinθ cosθ 0
? 0 0 0 1
?
点 P(x,y,z)在 Tx作用下得到 P’(x’,y’z,’),即
? x’ = x
? y’ = ycosθ - zsinθ
? z’ = ysinθ + zcosθ
?( 2) 绕 y轴旋转 θ 角度
? y坐标不变, x,z坐标发生变化 。
? 变换矩阵为:
? cosθ 0 - sinθ 0
? Ty = 0 1 0 0
? s inθ 0 cosθ 0
? 0 0 0 1
?点 P(x,y,z)在 Ty作用下得到 P’(x’,y’z,’),
即
? x’ = zsinθ + xcosθ
? y’ = y
? z’ = zcosθ - xsinθ
? ( 3) 绕 z轴旋转 θ 角度
? z坐标不变, x,y坐标发生变化 。
? 变换矩阵为:
? cosθ sinθ 0 0
? Tz = - sinθ cosθ 0 0
? 0 0 0 0
? 0 0 0 1
?
? 点 P(x,y,z)在 Tz作用下得到 P’(x’,y’z,’),即
? x’ = xcosθ -ysinθ
? y’ = xsinθ + ycosθ
? z’ = z
8.3.2 组合变换
? 与二维图形的组合变换一样, 可以通过对三维
立体图形顺序进行多种基本变换, 来实现复杂
的三维图形变换 。 下面通过一个实例来介绍三
维组合变换 。
? 例 3:在三维空间中, 绕任意轴的旋转变换
? 设旋转轴 AB由空间任意一点 A(xa,ya,za)及其方
向数 ( a,b,c) 定义, 空间一点 P(xp,yp,zp)绕 AB
轴旋转 θ 角到 P’(xp’,yp’,zp’),如图 8-3-3所示 。
? 即
? P’=[ xp’ yp’ zp’ 1]
? =P?Tab= [ xp yp zp 1] ?Tab
? y
z
x
图 8-3-3 绕任意轴的旋转变换
o
A
B
P
P’
θ
? 求组合变换矩阵 Tab的思想:以 A(xa,ya,za)为新
的坐标原点, 并使 AB分别绕 X轴, Y轴旋转适
当角度与 Z轴重合, 再绕 Z轴旋转 θ 角, 最后再
做上述变换的逆变换, 使 AB回到原来的位置 。
? ( 1) 使坐标原点平移到 A点, 原来的 AB在新的
坐标系中为 O’A,其方向数仍为 (a,b,c)。
? 变换矩阵为:
1 0 0 0
TA = 0 1 0 0
? 0 0 1 0
? - xa - ya - za 1
?
? ( 2) 让平面 AO’A’绕 X轴旋转 α 角
? 经旋转 α 角后, O’A就在 X’O’Z’平面上了 。
? 其中 α 是 O’A在 Y’O’Z’平面上的投影 O’A’与 Z’
轴的夹角, 如图 8-3-4( a) 所示 。 故有
? v=|O’A’|= √ b2+c2, cosα =c/v,
sinα =b/v
? 变换矩阵
? 1 0 0 0
? TRX = 0 cosα sinα 0
? 0 - sinα cosα 0
? 0 0 0 1
? ( 3) 让 O’A绕 Y’轴旋转 β 角
? O’A绕 Y’轴旋转 β 角后与 Z’轴重合, 如图 8-
3-4( b) 所示 。 此时, 从 Z’轴往原点看, β 角
是顺时针方向, 故 β 角取负值 。 故有
?
?u=|O’A|=√ a2+v2 =√ a2+b2 + c2,
cosβ =v/u,sinβ =a/u
?变换矩阵
? c os(-β ) 0 -sin(-β ) 0
? TRY = 0 1 0 0
? sin(-β ) 0 cos(-β ) 0
? 0 0 0 1
?
?
? ( 4) P绕 Z’轴旋转 θ 角
? 经过以上三步变换后, 就可以让 P绕 Z’轴旋
转 θ 角了 。
? 变换矩阵为
cosθ sinθ 0 0
? Tz = - sinθ cosθ 0 0
? 0 0 1 0
? 0 0 0 1
? ( 5) 求 TRY, TRX, TA 的逆变换, 回到 AB原
来的位置
? cos(β ) 0 -sin(β ) 0
? TRY -1 = 0 1 0 0
? sin(β ) 0 cos(β ) 0
? 0 0 0 1
?
? 1 0 0 0
? TRX -1 = 0 cos(-α ) sin(-α ) 0
? 0 - sin(-α ) cos(-α ) 0
? 0 0 0 1
? 1 0 0 0
? TA -1 = 0 1 0 0
? 0 0 1 0
? xa ya za 1
? 最后, 得出组合变换
? Tab = TA ?TRX? TRY? Tz ? TRY -1? TRX
-1? TA -1
8,4 投影变换
? 把三维形体变成二维图形表示的过程称为投影
变换 。 投影分为平行投影和透视投影 。 它们的
本质区别在于透视投影的投影中心到投影面之
间的距离是有限的, 而平行投影的投影的投影
中心则是无限的 。 如图 8-4-1所示 。
?
? 8-4-1 透视投影和平行投影
?投影变换的分类如下:
?
8.4.1 平行投影
? 平行投影是指透视中心在无限远处, 即平行透视
线所产生的投影 。 根据投影方向与投影面的夹角
可分成正平行投影和斜平行投影 。 当投影方向与
投影面的夹角为 90° 时, 得到的投影为正投影,
否则为斜投影 。 如图 8-4-2所示 。 平行投影的特
点是能精确地反映物体的实际大小, 不会产生放
大或缩小 。
?1,正平行投影
?正平行投影根据投影面与坐标轴的夹角
又可分为两类:正投影和正轴测投影 。
当投影面与某一坐标轴垂直时, 得到的
投影为正投影, 也称为三视图, 这时投
影方向与这个坐标轴一致 。 否则, 得到
的投影为正轴测投影 。
?三视图有主视图, 侧视图和俯视图三种,
它们分别与 X轴, Y轴和 Z轴垂直 。 图 8-4-
3显示了一个小房子的三视图 。
? ( 1)主视图
? 0 0 0 0
? Tfont= 0 1 0 0
? 0 0 1 0
? 0 0 0 1
? P’=P? Tfont = [x y z 1] ? Tfont = [0 y z 1]
? x坐标为零, y,z坐标不变, 得到 YOZ平面上
的二维投影, 即主视图 。
? ( 2) 侧视图
? 1 0 0 0
? Tside= 0 0 0 0
? 0 0 1 0
? 0 0 0 1
? P’=P? Tside = [x y z 1] ? Tside = [x 0 z 1]
? y坐标为零,x,z坐标不变,得到 XOZ平面上
的二维投影,即侧视图。
? ( 3) 俯视图
? 1 0 0 0
? Ttop= 0 1 0 0
? 0 0 0 0
? 0 0 0 1
? P’=P? Ttop = [x y z 1] ? Ttop = [x y 0 1]
? z坐标为零, x,y坐标不变, 得到 XOY平面上
的二维投影, 即俯视图 。
? 三视图常用于工程制图, 因为在三视图上可以
测量距离和角度 。 但一种三视图上只有物体一
个面的投影, 所以单独从某一个方向的三视图
上是很难想象出物体的三维形状的, 只有将主,
测, 俯三个视图放在一起, 才能综合想象出物
体的空间形状 。
? 正轴侧投影分为等轴侧、正二侧和正三侧三种。
当投影面与三个坐标轴之间的夹角都相等时为
等轴侧;当投影面与两个坐标轴之间的夹角相
等时为正二侧;当投影面与三个坐标轴之间的
夹角都不相等时为正三侧。图 8-4-4是等轴侧、
正二侧和正三侧的示意图。投影方向垂直于投
影面。
? 2,斜平行投影
? 如果投影方向不垂直于投影平面的平行投影,
则称为斜平行投影 。 斜投影的特点是既能像三
视图那样在主平面上进行距离和角度测量, 又
能像正轴侧图那样同时反映物体的多个面, 因
此具有更强的立体效果 。
? 常用的两种斜投影是斜等侧和斜二侧 。 当投影
方向与投影面成 45° 角时, 得到的是斜等侧,
这时, 和投影面垂直的任何直线段, 其投影长
度不变, 图 8-4-5( a) 中的 AB=A’B’。 当投影
方 向 与 投 影 面 成 arctg(2) 的 角 度 时, 即
AB=2A’B’,得到的投影称为斜二侧, 如图 8-4-
5(b)所示 。
?下面求出一种斜投影的变换矩阵。如图
8-4-6所示,设投影面为 XY平面,投影方
向与投影面的夹角为 α, 投影线和 Z轴所
组成的平面与 XZ面的夹角为 β 。 点
P’(xp’,yp’,0)是点 P(0,0,z)在投影面上的斜
投影。
于是,
|OP’|=z?ctgα
xp’= | OP’|?cosβ = z?ctgα ?cosβ
yp’= | OP’|?sinβ = z?ctgα ?sinβ
对于空间任意一点 Q(x,y,z),在投影面上的斜投
影的坐标可以从图 8-4-7直接求出 。
xp = xp’+ x = z?ctgα ?cosβ + x
yp = yp’+y= z?ctgα ?sinβ +y
?因此可以得到变换矩阵
? 1 0 0 0
? Tobl= 0 1 0 0
? ctgα ?cosβ ctgα ?sinβ 0 0
? 0 0 0 1
?
?如果是斜等侧,则 α =45°,ctgα =1。
如果是斜二侧,则
α =arctg(2),ctgα =1/2。
8.4.2 透视投影
? 透视投影的视线(投影线)是从视点(观察点)
出发,视线是不平行的。如图 8-4-8,设投影中
心在坐标原点,投影面与 Z轴垂直,在 z=d的位
置上。点 P(x,y,z)在投影面上的投影点为
P’(xp,yp,d)。
? 下面计算出 xp,yp的值 。 由图 8-4-8(b),(c)得:
?
? 设透视变换矩阵为 Tper,则用齐次坐标可将上
述关系表示为:
? 1 0 0 0
? Tper= 0 1 0 0
? 0 0 1 1/d
? 0 0 0 0
? 则有,
?
? 于是得到:
? 从式 8-4-2可以看出, 物体透视投影的大小与物
体到投影中心的距离成反比, 即当投影面 ( d
值 ) 一定的情况下, 物体越远 ( z值越大 ),
则物体的投影就越小 ( xp和 yp) 。 这就是所谓
的透视缩小效应 。 这种效应十分类似于照相系
统和人的视觉系统 。
? 透视投影具有下面的特点,( 1) 等长的两条
直线段, 且平行于投影面, 但离投影中心近的
线段, 其透视投影大, 而离投影中心远的线段,
其透视投影小 。 也即透视投影不能真实反映物
体的精确尺寸和形状; ( 2) 透视投影的深度
感更强, 看上去更真实 。 因此, 透视投影场用
于医疗拍照等领域 。
? 对于透视投影,一束平行于投影面的平行线的
投影可保持平行,而不平行于投影面的平行线
的投影会汇聚到一点,这个点称为灭点。如图
8-4-9所示。灭点可以看作是无限远处的一点在
投影面上的投影。
? 透视投影的灭点有无限多个, 不同方向的平行
线在投影面上就能形成不同的灭点 。 坐标轴方
向的平行线在投影面上形成的灭点称为主灭点 。
因为有 X,Y,Z三个坐标轴, 所以主灭点最多
有三个 。 当某个坐标轴与投影面平行时, 则该
坐标轴方向的平行线在投影面上的投影仍然保
持平行, 不形成灭点 。
? 透视投影是按照主灭点的个数来分类,可分为
一点透视、两点透视和三点透视。一点透视是
一个主灭点,即投影面与一个坐标轴正交,与
另外两个坐标轴平行。两点透视有两个主灭点,
即投影面与两个坐标轴相交,与另一个坐标轴
平行。三点透视有三个主灭点,即投影面与三
个坐标轴都相交。
8,5 算法与实践
? ( 一 ) 实验目的
? 进一步加深对常用的二维几何变换的理解, 如
平移, 旋转, 放大缩小等 。 掌握变换顺序和变
换矩阵 。
? ( 二 ) 实验任务
? 1,通过二维几何变换的数学模型, 编写平
移, 旋转, 放缩, 对称变换;
? 2,加入鼠标功能, 实现交互式移动图形;
?( 三 ) 实验内容和实验步骤
?任务一:根据数学模型, 编写几何变换
程序
?1,平移变换
? 将图形上的点 ( x,y) 分别在 x方向和
y方向分别移动 dx 和 dy,则变换后的
(x’,y’)坐标值为:
? x’=x+dx,y’=y+dy
?变换矩阵表示为:
? 1 0 0
? [x’ y’ 1]=[x y 1] 0 1 0
? dx dy 1
? 下面程序通过一个正弦曲线, 来进行平移变换 。
? 步骤 1:建立 MoveCmd工程, 在 OnDraw()函数中输入如下代码,
生成正弦曲线 ;
? void CMoveCmdView::OnDraw(CDC* pDC)
? {
? CMoveCmdDoc* pDoc = GetDocument();
? ASSERT_VALID(pDoc);
? // TODO,add draw code for native data here
? int x,y,px,py,xx,yy,dx,dy;
? double hx;
? CPoint tp;
? for(x=-180;x<=180;x++)
? {
? hx=x*3.1415926/180;
? y=(int)(100*sin(hx)); //正玄函数
? px=320+x;py=240-y;
? tp.x=px;tp.y=py;
? pDC->SetPixel(tp,RGB(255,0,0));
? }
? }
?注:由于使用了数学函数 sin(),所以应在
程序头部加入,#include“math.h”。
?步骤 2:将曲线沿 x方向, 按每隔 10个像素
平移一次, 显示结果;
? 在 for(x=-180;x<=180;x++){… }前加入循
环语句:
? for (xx=-50;xx<=50;xx=xx+10)
?并且将 px=320+x改为,px=320+x+xx。
?重新编译, 运行, 察看运行结果 。
?步骤 3:将曲线沿 y方向, 按每隔 10个像素
平移一次, 显示结果;
?在 for(x=-180;x<=180;x++){… }前加入循
环语句:
?for (yy=-50;yy<=50;yy=yy+10)
?将 py=240-y修改为 py=240-y-yy; 重新编
译, 运行, 察看运行结果 。
?步骤 4:编写 dx=80,dy=-50时, 程序运行
结果 。
? 在 for(x=-180;x<=180;x++){… }前加入
语句,dx=80;dy=-50;
? px=320+x;py=240-y;修改为:
px=320+x+dx;py=240-y+dy;
? 2,旋转变换
? 将图形上的点 ( x,y) 旋转 θ 角度, 得到新的
坐标 (x’,y’)为:
? x’=xcosθ -ysinθ,y’=xsinθ +ycosθ ;
? 变换矩阵表示为:
? cosθ sinθ 0
? [x’ y’ 1]=[x y 1] -sinθ cosθ 0
? 0 0 1
?
? 下面程序通过一个正弦曲线, 从 0~180度, 每
隔 10度旋转一次 。
? 步骤 1:建立工程 RotateCmd,在 OnDraw()中
编写程序如下:
? void CMoveCmdView::OnDraw(CDC* pDC)
? {
? CMoveCmdDoc* pDoc = GetDocument();
? ASSERT_VALID(pDoc);
? // TODO,add draw code for native data here
? int x,y,px,py,xx,yy,dx,dy;
? double hx;
? CPoint tp;
? for(x=-180;x<=180;x++)
? {
? hx=x*3.1415926/180;
? y=(int)(100*sin(hx)); //正玄函数
? px=320+x;py=240-y;
? tp.x=px;tp.y=py;
? pDC->SetPixel(tp,RGB(255,0,0));
? }
? }
? 3,比例变换
? 比例变换公式为,x’=x..Sx,y’=y.Sy; 其中
Sx,Sy分别为 x,y方向的放缩比例系数 。
? 变换矩阵表达式为:
? Sx 0 0
? [x’ y’ 1]=[x y 1] 0 Sy 0
? 0 0 1
?
? 下面通过不同的比例系数来显示程序运行结果 。
? ( 1) Sx=Sy= 1.5; 等比例放大
? ( 2) Sx=Sy= 0.5; 等比例缩小
? ( 3) Sx=1.5; Sy=0.5; 不等比例放缩
? 建立工程文件 ScaleCmd,在 OnDraw()函数中
编写如下程序。
? void CScaleCmdView::OnDraw(CDC* pDC)
? {
? CScaleCmdDoc* pDoc = GetDocument();
? ASSERT_VALID(pDoc);
? // TODO,add draw code for native data here
? int x,y,px,py,xx,yy,dx,dy;
? double hx,sx,sy;
? CPoint tp;
? // sx=1.5;sy=1.5; //等比例放大
? //sx=0.5;sy=0.5; //等比例缩小
? sx=1.5;sy=0.5; //不等比例放缩
? //放缩前
? for(x=-180;x<=180;x++)
? {
? hx=x*3.1415926/180;
? y=(int)(100*sin(hx)); //正玄函数
? px=320+x;py=240-y;
? tp.x=px;tp.y=py;
? pDC->SetPixel(tp,RGB(255,0,0));
? }
? //放缩后
? for(x=-180;x<=180;x++)
? {
? hx=x*3.1415926/180;
? y=(int)(100*sin(hx)); //正玄函数
? px=320+(int)x*sx;py=240-(int)y*sy; //比例变换
? tp.x=px;tp.y=py;
? pDC->SetPixel(tp,RGB(0,0,255));
? }
? }
? 4,对称变换
? 包括以 x轴对称, y轴对称和原点 O对称三种 。
由于屏幕坐标只有第一象限, 我们可以将原点
平移到 ( 320,240) 处 。 在第一象限画出一个
三角形, 然后分别求出三个对称图形 。
? 步骤 1, 建 立 工 程 文 件 symmetryCmd,在
OnDraw()函数中编写如下程序:
? void CSymmetryCmdView::OnDraw(CDC* pDC)
? {
? CSymmetryCmdDoc* pDoc = GetDocument();
? ASSERT_VALID(pDoc);
? // TODO,add draw code for native data here
? CPoint
p1,p2,p3,p11,p21,p31,p12,p22,p32,p13,p23,p33;
? //绘出以 ( 320,240) 为原点的坐标轴
?
? pDC->MoveTo(5,240);pDC->LineTo(640,240);
? pDC->MoveTo(320,5);pDC->LineTo(320,400);
? pDC->TextOut(640,235,"x轴 ");
? pDC->TextOut(315,400,"y轴 ");
? //在第一象限定义一个三角形
? p1.x=400;p1.y=260;p2.x=480;p2.y=350;p3.x=350;p3.y=35
0;
? pDC->MoveTo(p1);
? pDC->LineTo(p2); pDC->LineTo(p3); pDC-
>LineTo(p1);
? pDC->TextOut(400,360,"第一象限 ");
? //x轴对称, 即 x=320线
? p11.x=p1.x; p11.y=240-(p1.y-240);
? p21.x=p2.x; p21.y=240-(p2.y-240);
? p31.x=p3.x; p31.y=240-(p3.y-240);
?
? pDC->MoveTo(p11);
? pDC->LineTo(p21); pDC->LineTo(p31);
pDC->LineTo(p11);
? pDC->TextOut(400,100,"第四象限 ");
? //y轴对称, 即 y=240
? p12.x=320-(p1.x-320); p12.y=p1.y;
? p22.x=320-(p2.x-320); p22.y=p2.y;
? p32.x=320-(p3.x-320); p32.y=p3.y;
? pDC->MoveTo(p12);
? pDC->LineTo(p22); pDC->LineTo(p32);
pDC->LineTo(p12);
? pDC->TextOut(200,360,"第二象限 ");
?
? //原点 O对称
? p13.x=320-(p1.x-320); p13.y=240-(p1.y-240);
? p23.x=320-(p2.x-320); p23.y=240-(p2.y-240);
? p33.x=320-(p3.x-320); p33.y=240-(p3.y-240);
? pDC->MoveTo(p13);
? pDC->LineTo(p23); pDC->LineTo(p33);
pDC->LineTo(p13);
? pDC->TextOut(200,100,"第三象限 ");
? }
任务二:利用鼠标实现交互式
移动图形
? 步骤 1:建立工程文件 MouseMoveObject;
? 步骤 2:建立在程序设计中的成员变量;
? public:
? CPoint p2; //直线段的起点和终点坐标
? CPoint p1;
? protected:
? CPoint mp2; //鼠标移动的两点, 用于直线
段的平移
? CPoint mp1;
? int m_ist; //0,表示鼠标第 1点; 1,表示鼠标
的第 2点
? 步骤 3:在构造函数中, 为成员变量赋初值;
? CMouseMoveObjectView::CMouseMoveObje
ctView()
? {
? // TODO,add construction code here
? //直线段初始化
? p1.x=0;p1.y=0;
? p2.x=0;p2.y=0;
? mp1.x=0;mp1.y=0;
? mp2.x=0;mp2.y=0;
? m_ist=0;//0,鼠标第一点, 1,鼠标第 2点
? }
? 步骤 4:在 OnDraw()函数中首先绘出直线段;
? void
CMouseMoveObjectView::OnDraw(CDC*
pDC)
? {
? CMouseMoveObjectDoc* pDoc =
GetDocument();
? ASSERT_VALID(pDoc);
? // TODO,add draw code for native data here
? //绘出一条直线
? p1.x=200;p1.y=100;
? p2.x=150;p2.y=300;
? pDC->MoveTo(p1);pDC->LineTo(p2);
? }
? 步骤 5:添加鼠标的左击和移动事件, 实现交
互式平移直线段;
? void
CMouseMoveObjectView::OnLButtonDown(U
INT nFlags,CPoint point)
? {
? // TODO,Add your message handler code here
and/or call default
? CDC *pDC=GetDC();
? pDC->SelectStockObject(NULL_BRUSH);
? if (!m_ist)
? {
? mp1=mp2=point;
? m_ist++;
? }
? else
? {
? mp2=point; //记录第二次单击鼠标的位置
? m_ist--; // 为下一次移动作准备
? //pDC->MoveTo(p1);pDC->LineTo(p2);
? }
? CView::OnLButtonDown(nFlags,point);
? }
? void
CMouseMoveObjectView::OnMouseMove(UI
NT nFlags,CPoint point)
? {
? // TODO,Add your message handler code
here and/or call default
?
? CDC *pDC=GetDC();
? int nDrawmode=pDC-
>SetROP2(R2_NOT); //设置异或绘图模式,
并保存原来绘图模式
? pDC->SelectStockObject(NULL_BRUSH);
? if(m_ist==1)
? {
? CPoint prePnt,curPnt;
? int dx,dy;
? prePnt=mp2; //获得鼠标所在的前一位置
? curPnt=point;
? //绘制橡皮筋线
? pDC->MoveTo(p1);pDC->LineTo(p2);// 用
异或模式擦出所画的直线
dx=curPnt.x-prePnt.x;dy=curPnt.y-prePnt.y;
? p1.x=p1.x+dx;p1.y=p1.y+dy;
? p2.x=p2.x+dx;p2.y=p2.y+dy;
? pDC->MoveTo(p1);pDC->LineTo(p2); //
用当前位置绘出直线
? mp2=point;
? }
? pDC->SetROP2(nDrawmode); //恢复原绘
图模式
? ReleaseDC(pDC); //释放设备环境
? CView::OnMouseMove(nFlags,point);
? }
? 步骤 6:编译, 调试程序, 察看运行结果 。
(四)实验分析和总结
?1,分析程序运行结果, 进一步完善程
序;
?2,参照 Autocad的交互式方式, 实现交
互式放缩, 旋转和对称变换 。
?写出实验体会和小结,总结通过本次实
验,学习和掌握了哪些知识点?
? 在计算机图形系统中, 经常需要对基本图形进
行变换, 例如:平移, 旋转, 放缩, 对称和投
影等 。 一幅基本的图形包含两组信息, 一组是
图形的几何信息, 如图形的顶点坐标, 另一组
是图形的拓扑信息, 即图形各顶点之间的关系 。
图形的几何变换是指图形的几何信息发生改变,
而拓扑关系不变 。 所以, 图形的几何变换只考
虑图形各顶点坐标的变换 。 图形变换分为两种,
一种是图形不变, 而坐标系发生变化, 另一种
是坐标系不变, 而图形位置和形状发生变化 。
后一种情况是本章讲解的重点, 分为二维图形
几何变换, 三维几何变换和投影变换等 。
8,1 坐标系和坐标变换
?8,1,1坐标系
?对图形对象的描述, 图形的输入输出,
都是在一定的坐标系中进行的 。 常用的
坐标系分为用户坐标系, 设备坐标系和
规格化的坐标系三种 。 不同的坐标系有
不同的坐标原点和坐标刻度, 其取值范
围及适用的对象也有所不同 。
?在几何学中, 为了用数字描述空间的物
体, 包括物体的大小, 形状和位置, 必
须引进笛卡尔坐标系 。 用户总是习惯于
在自己熟悉的坐标系中描述客体或绘制
图形, 这个用户定义客体的坐标系, 称
为用户坐标系, 或称为客体坐标系 。 常
用的用户坐标系有直角坐标系, 极坐标
系, 对数坐标系, 球形坐标系等 。 在图
形系统中, 一般只用到直角坐标系 。 直
角坐标系又称为宇宙坐标系, 可以分为
二维直角坐标系合三维直角坐标系 。
? 设备坐标系一般是二维坐标系, 图形的输出在
设备坐标系中进行 。 设备坐标系包括有:绘图
仪坐标系和显示屏幕坐标系 。
? 规格化坐标系是与设备无关的坐标系, 用来构
造与设备无关的图形系统 。 通常取无量纲的单
位长度作为在规格化坐标系中图形输入输出的
有效空间, x和 y方向的取值范围为 [0,1]。
用户坐标系、规格化坐标系和设备坐标系
三者之间的关系如图 8.1所示。
? 图 8.1 三种坐标系之间的关系
Y Y
Y
Y
X X
X
X
(Xw,Yw )
Hw
Ww(Xlw,Ybw)
1
1
(Xn,Yn )
用户坐标系 规格化坐标系 设备坐标系
规格化变换
或者
(0,0)
8,1,2 窗口与视口
?1,用户域和窗口
?用户用来定义设计对象的实数域称为用
户域, 也称为用户空间 。 人们所要描述
的图形均在用户域中进行定义 。 从理论
上说, 用户域是连续的, 无限的 。
?用户域中定义的对象可能很大, 很复杂,
用户可以指定其中感兴趣部分区域通过
屏幕显示出来, 通常称这个区域为窗口 。
就像人们站在房间里通过窗口往外看,
只能看到窗口范围内的景物, 人们选择
不同的窗口可以看到不同的景物 。 窗口
区一般是矩形区域, 可以用其左下角和
右上角的坐标来表示 。 窗口可以嵌套,
即在第一层窗口中可以再定义第二层窗
口 。 在某些情况下, 还可以定义圆形窗
口或多边形窗口 。
2.屏幕域和视图区
? 图形设备上用来输出图形的最大区域称为屏幕
域, 即显示器的显示区域, 它是有限的整数域,
用 显 示 器 分 辨 率 来 表 示, 如 640X480、
1024X768等 。
? 在计算机屏幕上, 一般的图形系统常常包含菜
单区, 工具栏, 图形显示区, 信息提示区等,
图形只是在图形显示区显示, 而不是在整个屏
幕上显示 。 我们把任何小于或等于屏幕域的区
域称为视图区 。 视图区由用户在屏幕域中用设
备坐标定义, 一般定义为矩形, 由其左下角坐
标和右上角坐标来定义 。 在一个计算机屏幕上,
可以定义多个视图区, 分别显示不同的图形 。
8,1,3 坐标变换
?由于窗口是在用户域中定义的, 而视图定
义在计算机屏幕上, 如果要将用户域中窗
口内的景物在计算机屏幕的视图中显示出
来, 就必须求出图形在窗口区和视图区之
间的转换关系, 这就是窗口与视图之间的
坐标变换 。
?设矩形窗口的左下角坐标为( WXL,WYB),
右上角坐标为( WXR,WYT)。 在计算机屏
幕上定义的视图区的左下角坐标为
( VXL,VYB),右上角坐标为( VXR,VYT)。
如图 8-2所示,则在窗口区内的一点( Xw,Yw)
与视图区中的对应的一点( XV,YV) 存在如下
的转换关系:
图 8-1 窗口区与视图区的对应关系
(式 8-1-1)
若令:
a=( VXR-VXL)/( WXR-WXL)
b= VXL - WXL,( VXR-VXL)/( WXR-WXL)
c=( VYT-VYB)/( WYT-WYB)
d= VYB - WYB,( VYT-VYB)/( WYT-WYB)
则式 8-1-1可以简化为:
XV = a,Xw +b
YV =c,Yw +d (式 8-1-2)
?其中,a和 c分别反映了视图区和窗口区
之间在 x和 y方向上的伸缩比,b和 d则分
别反映了定位点在 x和 y方向上的偏移量。
显然,如果 a=c=1,b=d=0,则表示窗口
区和视图区的大小相等。若 a≠ c,则图
形会发生畸变。例如,在窗口区内的一
个圆,在视图区中则显示为一个椭圆。
因此,应当采取措施加以避免。
8,2 二维图形的几何变换
?二维图形的几何变换是指在不改变图形
连线次序的情况下,对一个平面点集进
行线性变换。对于线框图的变换,把图
形的一系列顶点作几何变换后,连接新
的顶点系列,即可产生出变换后的新图
形。图形变换分两种情况,一是图形的
相对位置发生改变,如平移、旋转和对
称变换,另一种是图形的形状发生变化,
如图形的缩放、错切或压缩变换。
8.2.1 二维图形几何变换的数
学表示
?1,二维图形几何变换的一般表示
?在二维空间中, 可以用一个行向量 [x,y]或
一个列向量 来表示一个点的坐标 。 二
维图形是一个平面点集 M,可以用 NX2矩
阵来表示, 其中 N为定点数, 矩阵 M表示
如下:
? M= ( 式 8-2-1)
x
y
x1 y1
x2 y2
.,
.,
.,
xn yn
? 设 P=[xi yi]为图形上的任意一点的坐标,
P’=[ xi ’ yi’]表示 P点经某种变换后新位置的坐
标 。 对于二维变换, 一般分为下面三种情况:
? ( 1) 对于平移变换, 设 Tx为点 P沿 X方向的平
移量, Ty为沿 Y方向的平移量, 则有:
? xi ’= xi + Tx
? yi ’= yi + Ty ( 式 8-2-2)
? Tx 和 Ty 是平移量,有正负之分。当平移方
向与 X轴一致时,Tx值为正,否则 Tx值为负;
当平移方向与 Y轴一致时,Ty值为正,否则 Ty
值为负;如图 8-2-1所示。
?(2)对于比例变换 ( 放缩 ), 则是给定 P
点相对于坐标原点沿 X方向的比例系数 Sx
和沿 Y方向的比例系数 Sy,经变换后, 则
有:
? xi ’= Sx, xi
?yi ’= Sy, yi ( 式 8-2-3)
?当 Sx = Sy <1时, 图形缩小;
?当 Sx = Sy =1时, 图形不变;
?当 Sx = Sy >1时, 图形放大;
?当 Sx ≠ Sy 时, 图形发生畸变;不考虑
这种情况 。
如图 8-2-2所示。注意图形放大或缩小时,
图形位置都发生了变化。
Tx
Ty
y
x
图 8-2-1 平移变换
Sx = Sy
<1
Sx = Sy >1
y
x
图 8-2-2 比例变换
Sx = Sy =1
? 3) 对于旋转变换, 先讨论平面上点绕坐标原
点的旋转变换 。
? 一个平面图形绕坐标原点逆时针旋转 θ 角
度, 图形的形状保持不变, 但图形各顶点的位
置坐标相应地发生了改变 。 如图 8-2-3所示, 可
以得到旋转后的坐标 。
? 图 8-2-3 旋转变换
? 设 A(x,y)绕原点逆时针旋转 θ 角度后, 新位置
的坐标为 A’(x’,y’),旋转半径 R=OA=OA’
? 因为:
A(x,y)
y
x
图 8-2-3 旋转变换
C
A’(x’,y’)
B
C’
B’
αθO
? Cosα =x/R,Sinα =y/R
? x’=RCos(θ +α )
? =R(Cosθ Cosα -Sinθ Sinα )
? =xCosθ -ySinθ
? y’=RSin(θ +α )
? =R(Sinθ Cosα +Cosθ Sinα )
? =xSinθ +yCosθ
? 即:
? x’= xCosθ -ySinθ
? y’=xSinθ +yCosθ ( 式 8-2-4)
? 注:( 1)式 8-2-4是绕原点旋转;
? ( 2)逆时针旋转,θ 角度为正。
2.二维图形几何变换的齐次
坐标表示
?对于上述常用的二维几何变换, 我们希
望用一种统一的矩阵方式来表示, 这就
需要用齐次坐标来表示 。
? 所谓齐次坐标表示法就是用 n+1维向量
表示一个 n维向量 。 在 n维空间中, 点的
位置矢量具有 n 个坐标分量
( P1,P2,…,Pn), 且是唯一的 。 若用齐
次坐标表示时, 此向量有 n+1个坐标分量
( hP1,hP2,…,hPn,h),且不唯一 。
?二维齐次坐标的一般表示形式为 [hX,hY,h]。
当 h=1 时, 二维坐标点的齐次坐标为
[x,y,1]; 当 h=2时, 二维坐标点的齐次坐
标为 [2x,2y,2]。 例如, [2,3,1],[2,6,
2],[6,9,3]都表示二维空间的点 [2,3]。
所以, 只有当 h=1时, 二维点的齐次坐标
中的 x,y数值才与二维坐标中点的位置矢
量的 x,y值相等 。
?若已知一个其次坐标形式为 [hX,hY,h],则
位置矢量
? x=hX/h,y=hY/h
? 我们可以用齐次坐标表示法 P=[x,y,1]来代表二
维平面内的一个点, 用 3X3矩阵表示变换矩阵 。
若令变换矩阵 a b p
? T= c d q
? l m s
? 则, 点 P经矩阵 T作用后得到
? [X Y H]=[x y 1]
? =[ax+cy+l bx+dy+m px+qy+s]
? 从而可以求出变换后点 P’的二维直角坐标为:
? x’=X/H = ( ax+cy+l)/( px+qy+s)
? y’=Y/H= (bx+dy+m)/( px+qy+s)
? 上述过程, 称为齐次坐标的正常化 。
a b p
c d q
l m s
8.2.2 基本的二维图形几何变
换
? 1,平移变换
? 在变换矩阵中, 取 l=Tx,m=Ty,l和 m分别表
示点 P(x,y)沿 X,Y方向的平移量 。 则平移变换可
以表示为,P’=P.T,其中平移矩阵
? T= 1 0 0
? 0 1 0
? Tx Ty 1 ( 式 8-2-5)
? 1 0 0
? 即 P’=P.T=[x y 1] 0 1 0 =[x + Tx y + Ty 1]
? Tx Ty 1
? 因齐次坐标中的 h=1,规范化后得到
?
? x’=x + Tx
? y’= y + Ty
?与式 8-2-2一致 。 说明可以采用上述平移矩阵来对平面图形进
行平移变换 。 对于一个平面点集矩阵 M,如式 8-2-1所示, 可
以通过矩阵运算来得到变换后所有顶点的新位置坐标 M’。?
?
M’=M.T= = =?
?如果点 P(x,y)经 T1变换后平移了 ( Tx1,Ty1), 然后再经 T2
变换后又平移了 ( Tx2,Ty2), 那么将产生什么结果呢? 从
直观上, 应该是平移了 ( Tx1+ Tx2,Ty1+ Ty2), 那么用齐
次坐标表示应如何描述呢? 首先令?
P’=P? T1?
P’’=P’? T2=P? T1? T2
x1 y1 1
x2 y2 1
.,,
.,,
.,,
xn yn 1
1 0 0
0 1 0
Tx Ty 1
x1 + Tx y1 + Ty 1
x2 + Tx y2 + Ty 1
.,,
.,,
.,,
xn + Tx yn + Ty 1
x1’ y1’ 1
x2’ y2’ 1
.,,
.,,
.,,
xn’ yn’ 1
?其中,
?
?
?这确实说明了实际的平移量是 ( Tx1 + Tx2,
Ty1 + Ty2), 也就是说, 连续的平移变换
是平移量相加 。 在齐次坐标表示中, 可
用矩阵相乘来描述 。
? 2,比例变换
? 在变换矩阵 T中, 取 a=Sx,d=Sy,它们分别表
示点 P(x,y)沿 X和 Y方向相对原点的比例变换系
数, 比例变换矩阵 T为:
? T = Sx 0 0
? 0 Sy 0
? 0 0 1
? ( 式 8-2-6)
? 则比例变换可表示为:
? P’=P?T =[x y 1] Sx 0 0
0 Sy 0 = [x Sx y Sy 1 ]
0 0 1
?
?齐次坐标规范化后得
? x’= x Sx
? y’= y Sy
?此式与式 8-2-3相一致。这说明比例变换
可以用比例变换矩阵乘法来处理。
?连续的比例变换可以通过连续的矩阵乘
法来实现 。 例如, 点 P(x,y)经比例变换
T1(Sx1,Sy1)后, 再经比例变换 T2(Sx2,
Sy2),那么, 最终的比例变换矩阵
? 比例变换矩阵的另一种形式是:
? T = 1 0 0
? 0 1 0
? 0 0 s ( 式 8-2-7)
? 比例变换可表示为:
? P’=P?T =[x y 1] 1 0 0
? 0 1 0 =[x y s]
? 0 0 s
? 规范化后得到:
?
? 说明式 8-2-7是一个等比例变换, s是比例变换
系数 。 当 s>1时, 图形缩小;当 s=1时, 图形大
小不便;当 s<1时, 图形放大;
? 3,旋转变换
? 旋转变换矩阵为:
? T= cosθ sinθ 0
? - sinθ cosθ 0
? 0 0 1 (式 8-2-8)
? 其中, θ角度由正负之分, 即点 P在 XY平面的
内绕原点逆时针旋转所形成的角度为正, 反之
为负 。
? P’=P?T =[x y 1] cosθ sinθ 0
? - sinθ cosθ 0
? 0 0 1
? =[ xCosθ-ySinθ xSinθ+yCosθ 1]
? 规范化后得到:
? x’= xCosθ-ySinθ
? y’= xSinθ+yCosθ
? 与式 8-2-4相一致 。
? 两个连续的旋转变换应该是角度的相加 。 设点 P(x,y)经
旋转变换 T1(θ1角度 )后, 再经旋转变换 T2 (θ1角度 ),那
么, 最终的旋转变换矩阵
? T= T1? T2 = cosθ2 sinθ2 0 cosθ1 sinθ1 0
? - sinθ2 cosθ2 0 - sinθ1 cosθ1 0
? 0 0 1 0 0 1
? cosθ1 cosθ2-sinθ1 sinθ2 cosθ1 sinθ2+ sinθ1cosθ2 0
= - sinθ1 cosθ2-cosθ1 sinθ2 - sinθ1 sinθ2+ cosθ1cosθ2 0
0 0 1
?
= Cos(θ1+θ2) sin(θ1+θ2) 0
? - sin(θ1+θ2) cos(θ1+θ2) 0
? 0 0 1
?
?
? 4,对称变换
? 对称变换也称为反射变换或镜像变换 。
? ( 1) 对称于 Y轴
? 如图 8-2-4( a) 所示 。 P(x,y)点对称于 Y轴
的点 P’(x’,y’)应该满足条件:
? x’= -x
? y’= y
? 对称于 Y轴的变换矩阵:
? - 1 0 0
? TY = 0 1 0 ( 式 8-2-9)
? 0 0 1
? 对称于 Y轴的变换
? P’=P? TY =[x y 1] - 1 0 0
? 0 1 0 = [ -x y 1]
? 0 0 1
? 即可得到,x’= -x,y’= y 。
? ( 2) 对称于 X轴
? 如图 8-2-4( b) 所示 。 P(x,y)点对称于 X轴
的点 P’(x’,y’)应该满足条件:
? x’= x
? y’= -y
? 对称于 X轴的变换矩阵:
? TX = 1 0 0
? 0 - 1 0 ( 式 8-2-10)
? 0 0 1
? 对称于 Y轴的变换
? P’=P? TX =[x y 1] 1 0 0
? 0 -1 0 = [ x -y 1]
? 0 0 1
? 即可得到,x’= x,y’= - y 。
? ( 3) 对称于原点 O
? 如图 8-2-4( c) 所示 。 P(x,y)点对称于原点
O的点 P’(x’,y’)应该满足条件:
? x’= -x
? y’= -y
? 对称于 X轴的变换矩阵:
? To = - 1 0 0
? 0 - 1 0
? 0 0 1 ( 式 8-2-11)
? 对称于 Y轴的变换
? P’=P? To =[x y 1] - 1 0 0
? 0 -1 0
? 0 0 1 = [ -x -y 1]
? 即可得到,x’= -x,y’= - y 。
? ( 4) 对称于直线 y=x
? 如图 8-2-4( d) 所示 。 P(x,y)点对称于直线
y=x的点 P’(x’,y’)应该满足条件:
? x’= y
? y’= x
? 对称于 X轴的变换矩阵:
? Ty=x = 0 1 0
? 1 0 0
? 0 0 1 ( 式 8-2-12)
? 对称于 Y轴的变换
? P’=P? Ty=x =[x y 1] 0 1 0
? 1 0 0
? 0 0 1 = [ y x 1]
? 即可得到,x’= y,y’= x 。
? ( 5) 对称于直线 y=-x
? 如图 8-2-4( e) 所示 。 P(x,y)点对称于直线
y=-x的点 P’(x’,y’)应该满足条件:
? x’= -y
? y’= -x
? 对称于 X轴的变换矩阵:
Ty =-x = 0 - 1 0
? - 1 0 0
? 0 0 1 ( 式 8-2-11)
? 对称于 Y轴的变换
P’=P? Ty =-x =[x y 1] - 1 0 0
? 0 -1 0 = [ -x -y 1]
? 0 0 1
? 即可得到,x’= -x,y’= - y 。
图 8-2-4 二维图形的对称变换
? 5,错切变换
? 错切变换也称为剪切, 错位或错移变换 。
? ( 1) 沿 x轴方向关于 y的错切
? 变换矩阵
Ty->x= 1 0 0
? c 1 0 (式 8-2-12)
? 0 0 1
? 点 P(x,y)经 Ty->x作用后, 得到的 P’(x’,y’)。
? P’=P? Ty->x =[x y 1] 1 0 0
? c 1 0 = [x+cy y 1]
? 0 0 1
? 即 x’=x+cy
? y’=y
? 说明变换前和变换后 y值坐标保持不变, 而 x坐
标依赖于初始坐标值 ( x,y) 及参数 c的值呈线
性变化 。 图 8-2-5说明了矩形 ABCD经 Ty->x矩阵
错切后变为一个平行四边形, 并且 c=tgα, 如
果 c>0,则沿 +x方向错切;若 c<0,则沿 -x方向
错切 。
? 图 8-2-5沿 x轴方向关于 y的错切变换
?
? ( 2) 沿 y轴方向关于 x的错切
? 变换矩阵
Tx->y= 1 b 0
? 0 1 0 (式 8-2-12)
? 0 0 1
? 点 P(x,y)经 Tx->y作用后, 得到的 P’(x’,y’)。
? P’=P? Tx->y =[x y 1] 1 b 0
? 0 1 0 = [x y+bx 1]
? 0 0 1
?
? 即 x’=x
? y’=y + bx
? 说明变换前和变换后 x值坐标保持不变, 而 y坐
标与初始坐标值 ( x,y) 及参数 b有关 。 图 8-2-
6说明了矩形 ABCD经 Tx->y矩阵错切后变为一个平
行四边形, 并且 b=tgβ, 如果 b>0,则沿 +y方向
错切;若 b<0,则沿 -y方向错切 。
? 图 8-2-6沿 y轴方向关于 x的错切变换
?
8.2.3 组合变换
? 在上一节中, 可以将二维图形的变换矩阵写成
如下形式:
? 由虚线分成四个部分, 各部分的功能如下:
? ( 1) a b
? c d 实现图形的比例变换, 对称变换,
旋转变换和错切变换;
? ( 2) [l,m] 实现平移变换, l和 m分别为 x,y方
向的平移量, 有正, 负值之分;
? ( 3) [s] 使图形产生等比例的变换 。 s>1,图
形缩小; s=1,图形不变; 0<s<1,图形放大;
? ( 4) p
? q 的用在其它变换中, 这里不做讨论 。
? 在实际的图形系统应用中, 一个复杂的变换往
往是由多个基本变换组合产生的, 这就提出了
如何进行组合变换的问题 。 所谓二维图形的组
合变换, 就是指在 XY平面内, 对一个已定义
的图形, 按照一定的顺序进行多次变换而得到
的新图形 。 通常, 我们总是试图将一些复杂的
变换转换成多个基本的变换, 一步一步变换来
实现 。 分步变换可以用基本的变换矩阵连乘来
实现, 表示总体变换的效果 。 可用下面的式子
来表示:
? T=T1XT2X???XTn
?其中, T1,T2???Tn为每一步的基本变换
矩阵 。 在数学中, 我们知道矩阵乘法不
满足交换率, 即设 A,B是两个矩阵, 则
存在下面关系:
? A X B ≠ B X A
?因此,组合变换中的顺序是不能颠倒的。
下面通过两个示例来介绍组合变换。
?例 1:图形绕任意点 P0(x0,y0)旋转 θ 角度
的变换矩阵 。
?解:前面我们介绍的绕坐标原点旋转的
变换矩阵, 为了实现题意要求, 可以分
解为以下三步来实现, 如图 8-2-7所示 。
?
?第一步:将原图形 Ⅰ 中的旋转点 P0平移
到坐标原点, 得到图形 Ⅱ, 变换矩阵为
T1= 1 0 0
? 0 1 0
? - x0 - y0 1
?第二步:图形 Ⅱ 绕坐标原点 o旋转 θ 角度,
得到图形 Ⅲ,变换矩阵为
?
T2= cosθ sinθ 0
? -sinθ cosθ 0
? 0 0 1
? 第三步:将图形 Ⅲ 中对应旋转点平移到原来的
位置 P0,得到图形 Ⅳ, 变换矩阵为
? 1 0 0
? T3= 0 1 0
? x0 y0 1
? 因此,组合变换矩阵为,
1 0 0 cosθ sinθ 0 1 0 0
? T= T1X T2X T3 = 0 1 0 -sinθ cosθ 0 0 1 0
x0 y0 1 0 0 1 - x0 - y0 1
? cosθ sinθ 0
? = -sinθ cosθ 0
? x0 (1- cosθ ) + y0sinθ x0sinθ + y0(1- cosθ ) 1
?如果上图中的原图形为长方形, A(20,10),
B(50,10),C(50,30),D(20,30),要求长
方形绕 A点作逆时针方向旋转 30°, 求变
换后各顶点的坐标 。
?原图形长方形点集矩阵表示为:
? 20 10 1
?P = 50 10 1
? 50 30 1
? 20 30 1
?
?变换后长方形的各顶点坐标为:
?
? 通过组合变换矩阵直接计算出
A’(20,10),B’(45.98,25),
C’(35.98,43.32),D’(10,27.32),绘出变
换后的最终图形, 中间的变换过程不必
一一计算出来 。
? 例 2:如图 8-2-8所示的矩形 ABCD,要变换成
A’B’C’D’,要求 DA=D’A’,AB=2A’B’,写出
该过程的组合变换的变换矩阵 。
? 解:
? ( 1) 将矩形 ABCD( Ⅰ ) 平移 ( -5,-5), 让
A点与坐标原点 O重合, 得到图形 Ⅱ, 变换矩
阵为:
? 1 0 0
? T1= 0 1 0
? -5 -5 1
? (2) 将图形 Ⅱ 绕原点 O逆时针旋转 90°, 得到
图形 Ⅲ, 变换矩阵为:
? Cos90 sin90 0 0 1 0
? T2= -sin90 cos90 0 = -1 0 0
? 0 0 1 0 0 1
? ( 3) 将图形 Ⅲ 在 Y方向上缩小一半, 得到图形
Ⅳ, 变换矩阵为:
? 1 0 0
? T3= 0 0.5 0
? 0 0 1
? 注意:比例变换是相对于原点 O的, 因此, 不
能将图形 Ⅲ 移到原位后再缩小 。 请读者思考 。
? ( 4) 平移图形 Ⅳ, 使图形 Ⅳ 左下角移到 ( 5,5)
位置, 与原图形的 A点重合, 得到图形 Ⅴ 。 平
移量应该为 ( 8,5), 所以变换矩阵为:
?
? 1 0 0
? T4= 0 1 0
? 8 5 1
? 因此, 组合变换矩阵表示为:
? 这样, 组合变换后图形的顶点坐标计算如下:
?
?
8,3 三维图形的几何变换
? 在三维空间中, 我们也采用齐次坐标技术来描
述空间的各点坐标和各种变换 。 空间点 P(x,y,z)
的齐次坐标表示为 [x y z 1],变换矩阵 T用
4X4矩阵来表示 。
? 从功能上分为四个子矩阵:
? a b c
? ( 1) d e f
? g h i, 可以产生比例、对称、旋转、
? 等基本变换;
?( 2) [l m n], 产生平移变换;
? p
?( 3) q, 产生透视投影变换;
? r
? ( 4) [s], 产生整体的比例变换;
?三维几何变换与上一节中介绍的二维几
何变换相同, 只不过三维空间的几何变
换比较复杂 。 从工程设计角度看, 三维
空间的几何变换直接与显示, 造型有关,
因此更重要一些 。
8.3.1 基本变换
? 1,比例变换
? ( 1) 局部变比
? 变换矩阵为:
? a 0 0 0
? T = 0 e 0 0
? 0 0 i 0
? 0 0 0 1
? 空间点 P(x,y,z)经变换后得到的坐标表示为:
? P’=P?T=[x y z 1] ?T=[ax ey iz 1]
? 其中, a,e,i分别为 x,y,z三个方向的缩放
系数 。
?( 2) 整体变比
?变换矩阵为:
? 1 0 0 0
? T = 0 1 0 0
? 0 0 1 0
? 0 0 0 s
? 规范化空间点 P(x,y,z)经变换后得到的坐
标表示为:
? P’=P?T=[x y z 1] ?T=[x y z s]
[x/s y/s z/s 1]
?即 x’=x/s,y’=y/s,z’=z/s。
? 2,平移变换
变换矩阵为:
? 1 0 0 0
? T = 0 1 0 0
? 0 0 1 0
? l m n 1
? P’=P?T=[x y z 1] ?T=[x+ l y+m z+n 1]
? 即 x’= x+l
? y’= y+m
? z’= z+n
? 其中, l,m,n分别是 x,y,z三个方向的位移
量, 并且位移量有正负之分, 与 x,y,z方向
一致的位移量为正, 否则为负 。
? 3,对称变换
? 三维图形的对称变换包括对坐标原点, 坐标轴
和坐标平面三种对称变换 。 这里主要讨论对坐
标平面的对称变换 。
? ( 1) 相对于 XY平面的对称变换
? 三维空间点 P( x,y,z) 相对于 XY平面的对称点
P’,x,y坐标不变, z坐标取反 。 如图 8-3-1所
示 。 所以, 变换矩阵为:
? 1 0 0 0
? Txoy= 0 1 0 0
? 0 0 -1 0
? 0 0 0 1
? P’=P?T=[x y z 1] ?T=[x y -z 1]
? 即 x’ = x, y’ = y, z’ = - z
?( 2) 相对于 XZ平面的对称变换
?三维空间点 P( x,y,z) 相对于 XZ平面的
对称点 P’,x,z坐标不变, y坐标取反 。
变换矩阵为:
? 1 0 0 0
? Txoz= 0 -1 0 0
? 0 0 1 0
? 0 0 0 1
? P’=P?T=[x y z 1] ?T=[x -y z 1]
?即 x’ = x, y’ = - y, z’ = z
O x
z
y
P(x,y,z)
图 8-3-1 三维空间对称变换
?( 3) 相对于 YZ平面的对称变换
?三维空间点 P( x,y,z) 相对于 YZ平面的
对称点 P’,y,z坐标不变, x坐标取反 。
变换矩阵为:
? -1 0 0 0
?Tyoz= 0 1 0 0
? 0 0 1 0
? 0 0 0 1
? P’=P?T=[x y z 1] ?T=[- x y z 1]
?即 x’ = - x, y’ = y, z’ = z
?4,旋转变换
? 在三维空间中, 基本旋转变换是指空
间立体绕坐标轴旋转一定的角度, 各旋
转角度的正方向如图 8-3-2所示 。
O x
z
y
图 8-3-2 三维空间旋转变换
? ( 1) 绕 x轴旋转 θ 角度
? x坐标不变, y,z坐标发生变化 。
? 变换矩阵为:
? 1 0 0 0
? Tx = 0 cosθ sinθ 0
? 0 - sinθ cosθ 0
? 0 0 0 1
?
点 P(x,y,z)在 Tx作用下得到 P’(x’,y’z,’),即
? x’ = x
? y’ = ycosθ - zsinθ
? z’ = ysinθ + zcosθ
?( 2) 绕 y轴旋转 θ 角度
? y坐标不变, x,z坐标发生变化 。
? 变换矩阵为:
? cosθ 0 - sinθ 0
? Ty = 0 1 0 0
? s inθ 0 cosθ 0
? 0 0 0 1
?点 P(x,y,z)在 Ty作用下得到 P’(x’,y’z,’),
即
? x’ = zsinθ + xcosθ
? y’ = y
? z’ = zcosθ - xsinθ
? ( 3) 绕 z轴旋转 θ 角度
? z坐标不变, x,y坐标发生变化 。
? 变换矩阵为:
? cosθ sinθ 0 0
? Tz = - sinθ cosθ 0 0
? 0 0 0 0
? 0 0 0 1
?
? 点 P(x,y,z)在 Tz作用下得到 P’(x’,y’z,’),即
? x’ = xcosθ -ysinθ
? y’ = xsinθ + ycosθ
? z’ = z
8.3.2 组合变换
? 与二维图形的组合变换一样, 可以通过对三维
立体图形顺序进行多种基本变换, 来实现复杂
的三维图形变换 。 下面通过一个实例来介绍三
维组合变换 。
? 例 3:在三维空间中, 绕任意轴的旋转变换
? 设旋转轴 AB由空间任意一点 A(xa,ya,za)及其方
向数 ( a,b,c) 定义, 空间一点 P(xp,yp,zp)绕 AB
轴旋转 θ 角到 P’(xp’,yp’,zp’),如图 8-3-3所示 。
? 即
? P’=[ xp’ yp’ zp’ 1]
? =P?Tab= [ xp yp zp 1] ?Tab
? y
z
x
图 8-3-3 绕任意轴的旋转变换
o
A
B
P
P’
θ
? 求组合变换矩阵 Tab的思想:以 A(xa,ya,za)为新
的坐标原点, 并使 AB分别绕 X轴, Y轴旋转适
当角度与 Z轴重合, 再绕 Z轴旋转 θ 角, 最后再
做上述变换的逆变换, 使 AB回到原来的位置 。
? ( 1) 使坐标原点平移到 A点, 原来的 AB在新的
坐标系中为 O’A,其方向数仍为 (a,b,c)。
? 变换矩阵为:
1 0 0 0
TA = 0 1 0 0
? 0 0 1 0
? - xa - ya - za 1
?
? ( 2) 让平面 AO’A’绕 X轴旋转 α 角
? 经旋转 α 角后, O’A就在 X’O’Z’平面上了 。
? 其中 α 是 O’A在 Y’O’Z’平面上的投影 O’A’与 Z’
轴的夹角, 如图 8-3-4( a) 所示 。 故有
? v=|O’A’|= √ b2+c2, cosα =c/v,
sinα =b/v
? 变换矩阵
? 1 0 0 0
? TRX = 0 cosα sinα 0
? 0 - sinα cosα 0
? 0 0 0 1
? ( 3) 让 O’A绕 Y’轴旋转 β 角
? O’A绕 Y’轴旋转 β 角后与 Z’轴重合, 如图 8-
3-4( b) 所示 。 此时, 从 Z’轴往原点看, β 角
是顺时针方向, 故 β 角取负值 。 故有
?
?u=|O’A|=√ a2+v2 =√ a2+b2 + c2,
cosβ =v/u,sinβ =a/u
?变换矩阵
? c os(-β ) 0 -sin(-β ) 0
? TRY = 0 1 0 0
? sin(-β ) 0 cos(-β ) 0
? 0 0 0 1
?
?
? ( 4) P绕 Z’轴旋转 θ 角
? 经过以上三步变换后, 就可以让 P绕 Z’轴旋
转 θ 角了 。
? 变换矩阵为
cosθ sinθ 0 0
? Tz = - sinθ cosθ 0 0
? 0 0 1 0
? 0 0 0 1
? ( 5) 求 TRY, TRX, TA 的逆变换, 回到 AB原
来的位置
? cos(β ) 0 -sin(β ) 0
? TRY -1 = 0 1 0 0
? sin(β ) 0 cos(β ) 0
? 0 0 0 1
?
? 1 0 0 0
? TRX -1 = 0 cos(-α ) sin(-α ) 0
? 0 - sin(-α ) cos(-α ) 0
? 0 0 0 1
? 1 0 0 0
? TA -1 = 0 1 0 0
? 0 0 1 0
? xa ya za 1
? 最后, 得出组合变换
? Tab = TA ?TRX? TRY? Tz ? TRY -1? TRX
-1? TA -1
8,4 投影变换
? 把三维形体变成二维图形表示的过程称为投影
变换 。 投影分为平行投影和透视投影 。 它们的
本质区别在于透视投影的投影中心到投影面之
间的距离是有限的, 而平行投影的投影的投影
中心则是无限的 。 如图 8-4-1所示 。
?
? 8-4-1 透视投影和平行投影
?投影变换的分类如下:
?
8.4.1 平行投影
? 平行投影是指透视中心在无限远处, 即平行透视
线所产生的投影 。 根据投影方向与投影面的夹角
可分成正平行投影和斜平行投影 。 当投影方向与
投影面的夹角为 90° 时, 得到的投影为正投影,
否则为斜投影 。 如图 8-4-2所示 。 平行投影的特
点是能精确地反映物体的实际大小, 不会产生放
大或缩小 。
?1,正平行投影
?正平行投影根据投影面与坐标轴的夹角
又可分为两类:正投影和正轴测投影 。
当投影面与某一坐标轴垂直时, 得到的
投影为正投影, 也称为三视图, 这时投
影方向与这个坐标轴一致 。 否则, 得到
的投影为正轴测投影 。
?三视图有主视图, 侧视图和俯视图三种,
它们分别与 X轴, Y轴和 Z轴垂直 。 图 8-4-
3显示了一个小房子的三视图 。
? ( 1)主视图
? 0 0 0 0
? Tfont= 0 1 0 0
? 0 0 1 0
? 0 0 0 1
? P’=P? Tfont = [x y z 1] ? Tfont = [0 y z 1]
? x坐标为零, y,z坐标不变, 得到 YOZ平面上
的二维投影, 即主视图 。
? ( 2) 侧视图
? 1 0 0 0
? Tside= 0 0 0 0
? 0 0 1 0
? 0 0 0 1
? P’=P? Tside = [x y z 1] ? Tside = [x 0 z 1]
? y坐标为零,x,z坐标不变,得到 XOZ平面上
的二维投影,即侧视图。
? ( 3) 俯视图
? 1 0 0 0
? Ttop= 0 1 0 0
? 0 0 0 0
? 0 0 0 1
? P’=P? Ttop = [x y z 1] ? Ttop = [x y 0 1]
? z坐标为零, x,y坐标不变, 得到 XOY平面上
的二维投影, 即俯视图 。
? 三视图常用于工程制图, 因为在三视图上可以
测量距离和角度 。 但一种三视图上只有物体一
个面的投影, 所以单独从某一个方向的三视图
上是很难想象出物体的三维形状的, 只有将主,
测, 俯三个视图放在一起, 才能综合想象出物
体的空间形状 。
? 正轴侧投影分为等轴侧、正二侧和正三侧三种。
当投影面与三个坐标轴之间的夹角都相等时为
等轴侧;当投影面与两个坐标轴之间的夹角相
等时为正二侧;当投影面与三个坐标轴之间的
夹角都不相等时为正三侧。图 8-4-4是等轴侧、
正二侧和正三侧的示意图。投影方向垂直于投
影面。
? 2,斜平行投影
? 如果投影方向不垂直于投影平面的平行投影,
则称为斜平行投影 。 斜投影的特点是既能像三
视图那样在主平面上进行距离和角度测量, 又
能像正轴侧图那样同时反映物体的多个面, 因
此具有更强的立体效果 。
? 常用的两种斜投影是斜等侧和斜二侧 。 当投影
方向与投影面成 45° 角时, 得到的是斜等侧,
这时, 和投影面垂直的任何直线段, 其投影长
度不变, 图 8-4-5( a) 中的 AB=A’B’。 当投影
方 向 与 投 影 面 成 arctg(2) 的 角 度 时, 即
AB=2A’B’,得到的投影称为斜二侧, 如图 8-4-
5(b)所示 。
?下面求出一种斜投影的变换矩阵。如图
8-4-6所示,设投影面为 XY平面,投影方
向与投影面的夹角为 α, 投影线和 Z轴所
组成的平面与 XZ面的夹角为 β 。 点
P’(xp’,yp’,0)是点 P(0,0,z)在投影面上的斜
投影。
于是,
|OP’|=z?ctgα
xp’= | OP’|?cosβ = z?ctgα ?cosβ
yp’= | OP’|?sinβ = z?ctgα ?sinβ
对于空间任意一点 Q(x,y,z),在投影面上的斜投
影的坐标可以从图 8-4-7直接求出 。
xp = xp’+ x = z?ctgα ?cosβ + x
yp = yp’+y= z?ctgα ?sinβ +y
?因此可以得到变换矩阵
? 1 0 0 0
? Tobl= 0 1 0 0
? ctgα ?cosβ ctgα ?sinβ 0 0
? 0 0 0 1
?
?如果是斜等侧,则 α =45°,ctgα =1。
如果是斜二侧,则
α =arctg(2),ctgα =1/2。
8.4.2 透视投影
? 透视投影的视线(投影线)是从视点(观察点)
出发,视线是不平行的。如图 8-4-8,设投影中
心在坐标原点,投影面与 Z轴垂直,在 z=d的位
置上。点 P(x,y,z)在投影面上的投影点为
P’(xp,yp,d)。
? 下面计算出 xp,yp的值 。 由图 8-4-8(b),(c)得:
?
? 设透视变换矩阵为 Tper,则用齐次坐标可将上
述关系表示为:
? 1 0 0 0
? Tper= 0 1 0 0
? 0 0 1 1/d
? 0 0 0 0
? 则有,
?
? 于是得到:
? 从式 8-4-2可以看出, 物体透视投影的大小与物
体到投影中心的距离成反比, 即当投影面 ( d
值 ) 一定的情况下, 物体越远 ( z值越大 ),
则物体的投影就越小 ( xp和 yp) 。 这就是所谓
的透视缩小效应 。 这种效应十分类似于照相系
统和人的视觉系统 。
? 透视投影具有下面的特点,( 1) 等长的两条
直线段, 且平行于投影面, 但离投影中心近的
线段, 其透视投影大, 而离投影中心远的线段,
其透视投影小 。 也即透视投影不能真实反映物
体的精确尺寸和形状; ( 2) 透视投影的深度
感更强, 看上去更真实 。 因此, 透视投影场用
于医疗拍照等领域 。
? 对于透视投影,一束平行于投影面的平行线的
投影可保持平行,而不平行于投影面的平行线
的投影会汇聚到一点,这个点称为灭点。如图
8-4-9所示。灭点可以看作是无限远处的一点在
投影面上的投影。
? 透视投影的灭点有无限多个, 不同方向的平行
线在投影面上就能形成不同的灭点 。 坐标轴方
向的平行线在投影面上形成的灭点称为主灭点 。
因为有 X,Y,Z三个坐标轴, 所以主灭点最多
有三个 。 当某个坐标轴与投影面平行时, 则该
坐标轴方向的平行线在投影面上的投影仍然保
持平行, 不形成灭点 。
? 透视投影是按照主灭点的个数来分类,可分为
一点透视、两点透视和三点透视。一点透视是
一个主灭点,即投影面与一个坐标轴正交,与
另外两个坐标轴平行。两点透视有两个主灭点,
即投影面与两个坐标轴相交,与另一个坐标轴
平行。三点透视有三个主灭点,即投影面与三
个坐标轴都相交。
8,5 算法与实践
? ( 一 ) 实验目的
? 进一步加深对常用的二维几何变换的理解, 如
平移, 旋转, 放大缩小等 。 掌握变换顺序和变
换矩阵 。
? ( 二 ) 实验任务
? 1,通过二维几何变换的数学模型, 编写平
移, 旋转, 放缩, 对称变换;
? 2,加入鼠标功能, 实现交互式移动图形;
?( 三 ) 实验内容和实验步骤
?任务一:根据数学模型, 编写几何变换
程序
?1,平移变换
? 将图形上的点 ( x,y) 分别在 x方向和
y方向分别移动 dx 和 dy,则变换后的
(x’,y’)坐标值为:
? x’=x+dx,y’=y+dy
?变换矩阵表示为:
? 1 0 0
? [x’ y’ 1]=[x y 1] 0 1 0
? dx dy 1
? 下面程序通过一个正弦曲线, 来进行平移变换 。
? 步骤 1:建立 MoveCmd工程, 在 OnDraw()函数中输入如下代码,
生成正弦曲线 ;
? void CMoveCmdView::OnDraw(CDC* pDC)
? {
? CMoveCmdDoc* pDoc = GetDocument();
? ASSERT_VALID(pDoc);
? // TODO,add draw code for native data here
? int x,y,px,py,xx,yy,dx,dy;
? double hx;
? CPoint tp;
? for(x=-180;x<=180;x++)
? {
? hx=x*3.1415926/180;
? y=(int)(100*sin(hx)); //正玄函数
? px=320+x;py=240-y;
? tp.x=px;tp.y=py;
? pDC->SetPixel(tp,RGB(255,0,0));
? }
? }
?注:由于使用了数学函数 sin(),所以应在
程序头部加入,#include“math.h”。
?步骤 2:将曲线沿 x方向, 按每隔 10个像素
平移一次, 显示结果;
? 在 for(x=-180;x<=180;x++){… }前加入循
环语句:
? for (xx=-50;xx<=50;xx=xx+10)
?并且将 px=320+x改为,px=320+x+xx。
?重新编译, 运行, 察看运行结果 。
?步骤 3:将曲线沿 y方向, 按每隔 10个像素
平移一次, 显示结果;
?在 for(x=-180;x<=180;x++){… }前加入循
环语句:
?for (yy=-50;yy<=50;yy=yy+10)
?将 py=240-y修改为 py=240-y-yy; 重新编
译, 运行, 察看运行结果 。
?步骤 4:编写 dx=80,dy=-50时, 程序运行
结果 。
? 在 for(x=-180;x<=180;x++){… }前加入
语句,dx=80;dy=-50;
? px=320+x;py=240-y;修改为:
px=320+x+dx;py=240-y+dy;
? 2,旋转变换
? 将图形上的点 ( x,y) 旋转 θ 角度, 得到新的
坐标 (x’,y’)为:
? x’=xcosθ -ysinθ,y’=xsinθ +ycosθ ;
? 变换矩阵表示为:
? cosθ sinθ 0
? [x’ y’ 1]=[x y 1] -sinθ cosθ 0
? 0 0 1
?
? 下面程序通过一个正弦曲线, 从 0~180度, 每
隔 10度旋转一次 。
? 步骤 1:建立工程 RotateCmd,在 OnDraw()中
编写程序如下:
? void CMoveCmdView::OnDraw(CDC* pDC)
? {
? CMoveCmdDoc* pDoc = GetDocument();
? ASSERT_VALID(pDoc);
? // TODO,add draw code for native data here
? int x,y,px,py,xx,yy,dx,dy;
? double hx;
? CPoint tp;
? for(x=-180;x<=180;x++)
? {
? hx=x*3.1415926/180;
? y=(int)(100*sin(hx)); //正玄函数
? px=320+x;py=240-y;
? tp.x=px;tp.y=py;
? pDC->SetPixel(tp,RGB(255,0,0));
? }
? }
? 3,比例变换
? 比例变换公式为,x’=x..Sx,y’=y.Sy; 其中
Sx,Sy分别为 x,y方向的放缩比例系数 。
? 变换矩阵表达式为:
? Sx 0 0
? [x’ y’ 1]=[x y 1] 0 Sy 0
? 0 0 1
?
? 下面通过不同的比例系数来显示程序运行结果 。
? ( 1) Sx=Sy= 1.5; 等比例放大
? ( 2) Sx=Sy= 0.5; 等比例缩小
? ( 3) Sx=1.5; Sy=0.5; 不等比例放缩
? 建立工程文件 ScaleCmd,在 OnDraw()函数中
编写如下程序。
? void CScaleCmdView::OnDraw(CDC* pDC)
? {
? CScaleCmdDoc* pDoc = GetDocument();
? ASSERT_VALID(pDoc);
? // TODO,add draw code for native data here
? int x,y,px,py,xx,yy,dx,dy;
? double hx,sx,sy;
? CPoint tp;
? // sx=1.5;sy=1.5; //等比例放大
? //sx=0.5;sy=0.5; //等比例缩小
? sx=1.5;sy=0.5; //不等比例放缩
? //放缩前
? for(x=-180;x<=180;x++)
? {
? hx=x*3.1415926/180;
? y=(int)(100*sin(hx)); //正玄函数
? px=320+x;py=240-y;
? tp.x=px;tp.y=py;
? pDC->SetPixel(tp,RGB(255,0,0));
? }
? //放缩后
? for(x=-180;x<=180;x++)
? {
? hx=x*3.1415926/180;
? y=(int)(100*sin(hx)); //正玄函数
? px=320+(int)x*sx;py=240-(int)y*sy; //比例变换
? tp.x=px;tp.y=py;
? pDC->SetPixel(tp,RGB(0,0,255));
? }
? }
? 4,对称变换
? 包括以 x轴对称, y轴对称和原点 O对称三种 。
由于屏幕坐标只有第一象限, 我们可以将原点
平移到 ( 320,240) 处 。 在第一象限画出一个
三角形, 然后分别求出三个对称图形 。
? 步骤 1, 建 立 工 程 文 件 symmetryCmd,在
OnDraw()函数中编写如下程序:
? void CSymmetryCmdView::OnDraw(CDC* pDC)
? {
? CSymmetryCmdDoc* pDoc = GetDocument();
? ASSERT_VALID(pDoc);
? // TODO,add draw code for native data here
? CPoint
p1,p2,p3,p11,p21,p31,p12,p22,p32,p13,p23,p33;
? //绘出以 ( 320,240) 为原点的坐标轴
?
? pDC->MoveTo(5,240);pDC->LineTo(640,240);
? pDC->MoveTo(320,5);pDC->LineTo(320,400);
? pDC->TextOut(640,235,"x轴 ");
? pDC->TextOut(315,400,"y轴 ");
? //在第一象限定义一个三角形
? p1.x=400;p1.y=260;p2.x=480;p2.y=350;p3.x=350;p3.y=35
0;
? pDC->MoveTo(p1);
? pDC->LineTo(p2); pDC->LineTo(p3); pDC-
>LineTo(p1);
? pDC->TextOut(400,360,"第一象限 ");
? //x轴对称, 即 x=320线
? p11.x=p1.x; p11.y=240-(p1.y-240);
? p21.x=p2.x; p21.y=240-(p2.y-240);
? p31.x=p3.x; p31.y=240-(p3.y-240);
?
? pDC->MoveTo(p11);
? pDC->LineTo(p21); pDC->LineTo(p31);
pDC->LineTo(p11);
? pDC->TextOut(400,100,"第四象限 ");
? //y轴对称, 即 y=240
? p12.x=320-(p1.x-320); p12.y=p1.y;
? p22.x=320-(p2.x-320); p22.y=p2.y;
? p32.x=320-(p3.x-320); p32.y=p3.y;
? pDC->MoveTo(p12);
? pDC->LineTo(p22); pDC->LineTo(p32);
pDC->LineTo(p12);
? pDC->TextOut(200,360,"第二象限 ");
?
? //原点 O对称
? p13.x=320-(p1.x-320); p13.y=240-(p1.y-240);
? p23.x=320-(p2.x-320); p23.y=240-(p2.y-240);
? p33.x=320-(p3.x-320); p33.y=240-(p3.y-240);
? pDC->MoveTo(p13);
? pDC->LineTo(p23); pDC->LineTo(p33);
pDC->LineTo(p13);
? pDC->TextOut(200,100,"第三象限 ");
? }
任务二:利用鼠标实现交互式
移动图形
? 步骤 1:建立工程文件 MouseMoveObject;
? 步骤 2:建立在程序设计中的成员变量;
? public:
? CPoint p2; //直线段的起点和终点坐标
? CPoint p1;
? protected:
? CPoint mp2; //鼠标移动的两点, 用于直线
段的平移
? CPoint mp1;
? int m_ist; //0,表示鼠标第 1点; 1,表示鼠标
的第 2点
? 步骤 3:在构造函数中, 为成员变量赋初值;
? CMouseMoveObjectView::CMouseMoveObje
ctView()
? {
? // TODO,add construction code here
? //直线段初始化
? p1.x=0;p1.y=0;
? p2.x=0;p2.y=0;
? mp1.x=0;mp1.y=0;
? mp2.x=0;mp2.y=0;
? m_ist=0;//0,鼠标第一点, 1,鼠标第 2点
? }
? 步骤 4:在 OnDraw()函数中首先绘出直线段;
? void
CMouseMoveObjectView::OnDraw(CDC*
pDC)
? {
? CMouseMoveObjectDoc* pDoc =
GetDocument();
? ASSERT_VALID(pDoc);
? // TODO,add draw code for native data here
? //绘出一条直线
? p1.x=200;p1.y=100;
? p2.x=150;p2.y=300;
? pDC->MoveTo(p1);pDC->LineTo(p2);
? }
? 步骤 5:添加鼠标的左击和移动事件, 实现交
互式平移直线段;
? void
CMouseMoveObjectView::OnLButtonDown(U
INT nFlags,CPoint point)
? {
? // TODO,Add your message handler code here
and/or call default
? CDC *pDC=GetDC();
? pDC->SelectStockObject(NULL_BRUSH);
? if (!m_ist)
? {
? mp1=mp2=point;
? m_ist++;
? }
? else
? {
? mp2=point; //记录第二次单击鼠标的位置
? m_ist--; // 为下一次移动作准备
? //pDC->MoveTo(p1);pDC->LineTo(p2);
? }
? CView::OnLButtonDown(nFlags,point);
? }
? void
CMouseMoveObjectView::OnMouseMove(UI
NT nFlags,CPoint point)
? {
? // TODO,Add your message handler code
here and/or call default
?
? CDC *pDC=GetDC();
? int nDrawmode=pDC-
>SetROP2(R2_NOT); //设置异或绘图模式,
并保存原来绘图模式
? pDC->SelectStockObject(NULL_BRUSH);
? if(m_ist==1)
? {
? CPoint prePnt,curPnt;
? int dx,dy;
? prePnt=mp2; //获得鼠标所在的前一位置
? curPnt=point;
? //绘制橡皮筋线
? pDC->MoveTo(p1);pDC->LineTo(p2);// 用
异或模式擦出所画的直线
dx=curPnt.x-prePnt.x;dy=curPnt.y-prePnt.y;
? p1.x=p1.x+dx;p1.y=p1.y+dy;
? p2.x=p2.x+dx;p2.y=p2.y+dy;
? pDC->MoveTo(p1);pDC->LineTo(p2); //
用当前位置绘出直线
? mp2=point;
? }
? pDC->SetROP2(nDrawmode); //恢复原绘
图模式
? ReleaseDC(pDC); //释放设备环境
? CView::OnMouseMove(nFlags,point);
? }
? 步骤 6:编译, 调试程序, 察看运行结果 。
(四)实验分析和总结
?1,分析程序运行结果, 进一步完善程
序;
?2,参照 Autocad的交互式方式, 实现交
互式放缩, 旋转和对称变换 。
?写出实验体会和小结,总结通过本次实
验,学习和掌握了哪些知识点?