图形几何变换

在绘图过程中,经常需要对图形进行平移、缩小、放大和旋转等操作。Excel提供了专门的方法来实现图形的几何变换。[大谦Excel,dqexcel点com]

几何变换的基本原理

旋转变换使对象绕x,y或z轴旋转,逆时针旋转时角度为正。如果旋转角度为θ,则下面的矩阵定义绕各轴的旋转。

平移变换相对于当前位置移动对象,用距离tx,ty和tz指定平移。下面的矩阵显示了这些元素在变换矩阵中的位置。

缩放(比例)变换改变对象的大小,指定比例因子sx, sy和sz创建下面的矩阵:

默认变换矩阵是单位矩阵,可以用eye函数创建它。下面是单位矩阵:

图形平移

使用Shape对象的IncrementLeft方法,将该对象所表示的图形进行水平方向的平移。该方法有一个参数,参数的值大于0时图形向右移,值小于0时向左移。

使用Shape对象的IncrementTop方法,将该对象所表示的图形进行垂直方向的平移。该方法有一个参数,参数的值大于0时图形向下移,值小于0时向上移。

下面的例子创建一个添加水滴预设纹理的矩形区域,然后将该区域向右平移70个单位,向下平移50个单位。完整代码见:Samples->ch05 创建新图表->39 平移变换->py.py。

code.vba
Sub CreateChart()
  Dim shp As Shape
  Dim cht As Chart
  Set shp = ActiveSheet.Shapes.AddChart2()
  Set cht = shp.Chart
  cht.ChartType = xlXYScatter
  Dim ax1 As Axis
  Set ax1 = cht.Axes(1)
  Dim ax2 As Axis
  Set ax2 = cht.Axes(2)
  ax1.MinimumScale = 0
  ax1.MaximumScale = 400
  ax2.MinimumScale = 0
  ax2.MaximumScale = 300

  SetStyle cht
  cht.SeriesCollection.NewSeries

  Dim shp2 As Shape
  Dim x As Double
  Dim y As Double
  Dim w As Double
  Dim h As Double
  x = ShapeX(cht, 50)
  y = ShapeY(cht, 250)
  w = cht.PlotArea.InsideWidth / (ax1.MaximumScale - ax1.MinimumScale) * 200
  h = cht.PlotArea.InsideHeight / (ax2.MaximumScale - ax2.MinimumScale) * 100
  Set shp2 = cht.Shapes.AddShape(1, x, y, w, h)
  shp2.Fill.PresetTextured 5
End Sub

平移前后的图形如图2-41和图2-42所示。

Document Image Document Image

图2-41 平移前的图形 图2-42 平移后的图形

图形旋转

使用Shape对象的IncrementRotation方法实现图形的旋转。该方法绕Z轴旋转指定的角度。有一个参数,表示旋转的角度,以度为单位。为正值时顺时针方向旋转图形,为负值时逆时针方向旋转图形。

下面的例子创建一个添加水滴预设纹理的矩形区域,然后将该区域绕Z轴顺时针方向旋转30度。完整代码见:Samples->ch05 创建新图表->40 旋转变换->py.py。

code.vba
Sub CreateChart2()
  ‘…
  x = ShapeX(cht, 100)
  y = ShapeY(cht, 200)
  w = cht.PlotArea.InsideWidth / (ax1.MaximumScale - ax1.MinimumScale) * 200
  h = cht.PlotArea.InsideHeight / (ax2.MaximumScale - ax2.MinimumScale) * 100
  Set shp2 = cht.Shapes.AddShape(1, x, y, w, h)
  shp2.Fill.PresetTextured 5

  shp2.IncrementRotation 30
End Sub

图2-43为旋转后的矩形区域。

Document Image

图2-43 旋转后的图形

图形缩放

图形缩放又称为比例变换,是将给定的图形按照一定的比例放大或缩小。使用Shape对象的ScaleWidth方法和ScaleHeight方法可以指定水平方向和垂直方向的缩放比例,实现图形的缩放操作。

ScaleWidth方法和ScaleHeight方法都有3个参数,如表2-12所示。

表2-12 ScaleWidth方法和ScaleHeight方法的参数

名 称 必需/可选 数据类型 说 明
Factor 必需 Single 指定图形调整后的宽度与当前或原始宽度的比例
RelativeToOriginalSize 必需 MsoTriState 值为False时,相对于其当前大小进行缩放。 仅当指定的图形是图片或 OLE 对象时,才能将此参数指定为True
Scale 可选 Variant MsoScaleFrom类型的常量之一, 指定缩放图形时, 该图形的哪一部分保持在原有的位置

Scale参数的值为MsoScaleFrom枚举类型常量,表示缩放以后,图形那部分保持原来的位置。该参数的取值如表2-13中所示。

表2-13 Scale参数的取值

名 称 说 明
msoScaleFromBottomRight 2 图形的右下角保持在原有的位置
msoScaleFromMiddle 1 图形的中点保持在原有的位置
msoScaleFromTopLeft 0 图形的左上角保持在原有的位置

下面创建一个添加水滴预设纹理的矩形区域,然后对该区域水平方向缩小为原来宽度的0.75倍,垂直方向放大为原来高度的1.75倍。完整代码见:Samples->ch05 创建新图表->41 缩放变换->py.py。

code.vba
Sub CreateChart2()
  ‘…
  x = ShapeX(cht, 100)
  y = ShapeY(cht, 200)
  w = cht.PlotArea.InsideWidth / (ax1.MaximumScale - ax1.MinimumScale) * 200
  h = cht.PlotArea.InsideHeight / (ax2.MaximumScale - ax2.MinimumScale) * 100
  Set shp2 = cht.Shapes.AddShape(1, x, y, w, h)
  shp2.Fill.PresetTextured 5

  shp2.ScaleWidth 0.75, False
  shp2.ScaleHeight 1.75, False
End Sub

缩放后的图形如图2-44所示。

Document Image

图2-44 缩放以后的图形

图形翻转

图形的翻转也叫做图形的镜像变换,或对称变换。使用Shape对象的Flip方法实现图形的翻转。该方法是相对于水平对称轴或垂直对称轴作翻转的,它有一个参数,指定是水平翻转还是垂直翻转。水平翻转和垂直翻转对应的取值分别为0和1。

下面的例子创建一个矩形区域,为了便于对比,添加了木质纹理。然后对该区域进行水平翻转和垂直翻转操作。完整代码见:Samples->ch05 创建新图表->42 翻转变换->py.py。

code.vba
Sub CreateChart2()
  ‘…
  x = ShapeX(cht, 100)
  y = ShapeY(cht, 200)
  w = cht.PlotArea.InsideWidth / (ax1.MaximumScale - ax1.MinimumScale) * 200
  h = cht.PlotArea.InsideHeight / (ax2.MaximumScale - ax2.MinimumScale) * 100
  Set shp2 = cht.Shapes.AddShape(1, x, y, w, h)
  shp2.Fill.PresetTextured 22

  shp2.Flip 0
End Sub

翻转前的图形如图2-45所示。图2-46为原图形水平翻转后的图形。

Document Image Document Image

图2-45 原图形 图2-46 水平翻转

图2-47为垂直翻转后的结果,实现代码如下所示。完整代码见:Samples->ch05 创建新图表->43 翻转变换2->py.py。

Document Image

图2-47 垂直翻转

code.vba
Sub CreateChart3()
  ‘…
  x = ShapeX(cht, 100)
  y = ShapeY(cht, 200)
  w = cht.PlotArea.InsideWidth / (ax1.MaximumScale - ax1.MinimumScale) * 200
  h = cht.PlotArea.InsideHeight / (ax2.MaximumScale - ax2.MinimumScale) * 100
  Set shp2 = cht.Shapes.AddShape(1, x, y, w, h)
  shp2.Fill.PresetTextured 22

  shp2.Flip 1
End Sub