在绘图过程中,经常需要对图形进行平移、缩小、放大和旋转等操作。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。
root=os.getcwd() #获取当前工作路径
app=xw.App(visible=True,add_book=False) #创建Excel应用
wb=app.books.open(root+r'/data.xlsx',read_only=False) #打开数据文件返回工作簿对象
sht=wb.sheets('Sheet1') #获取指定工作表对象
shp=sht.api.Shapes.AddChart2() #创建空白图表
shp.Left=20
cht=shp.Chart #获取图表
cht.ChartType=xw.constants.ChartType.xlXYScatter #图表类型为散点图
ax1=cht.Axes(1) #获取横轴
ax2=cht.Axes(2) #获取纵轴
ax1.MinimumScale=0 #横轴最小值
ax1.MaximumScale=400
ax2.MinimumScale=0 #纵轴最小值
ax2.MaximumScale=300
set_style(cht) #设置样式
cht.SeriesCollection().NewSeries() #新建序列
x=shape_x(cht,50)
y=shape_y(cht,250)
w=cht.PlotArea.InsideWidth/(ax1.MaximumScale-ax1.MinimumScale)*200
h=cht.PlotArea.InsideHeight/(ax2.MaximumScale-ax2.MinimumScale)*100
shp2=cht.Shapes.AddShape(1,x,y,w,h) #矩形区域
shp2.Fill.PresetTextured(5) #水滴预设纹理
shp2.IncrementLeft(70) #右移70
shp2.IncrementTop(50) #下移50
平移前后的图形如图2-41和图2-42所示。
图2-41 平移前的图形 图2-42 平移后的图形
图形旋转
使用Shape对象的IncrementRotation方法实现图形的旋转。该方法绕Z轴旋转指定的角度。有一个参数,表示旋转的角度,以度为单位。为正值时顺时针方向旋转图形,为负值时逆时针方向旋转图形。
下面的例子创建一个添加水滴预设纹理的矩形区域,然后将该区域绕Z轴顺时针方向旋转30度。完整代码见:Samples->ch05 创建新图表->40 旋转变换->py.py。
#... 省略部分代码
cht.SeriesCollection().NewSeries() #新建序列
x=shape_x(cht,100)
y=shape_y(cht,200)
w=cht.PlotArea.InsideWidth/(ax1.MaximumScale-ax1.MinimumScale)*200
h=cht.PlotArea.InsideHeight/(ax2.MaximumScale-ax2.MinimumScale)*100
shp2=cht.Shapes.AddShape(1,x,y,w,h) #矩形区域
shp2.Fill.PresetTextured(5) #水滴预设纹理
shp2.IncrementRotation(30) #顺时针方向旋转30度
图2-43为旋转后的矩形区域。
图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。
#... 省略部分代码
cht.SeriesCollection().NewSeries() #新建序列
x=shape_x(cht,50)
y=shape_y(cht,250)
w=cht.PlotArea.InsideWidth/(ax1.MaximumScale-ax1.MinimumScale)*200
h=cht.PlotArea.InsideHeight/(ax2.MaximumScale-ax2.MinimumScale)*100
shp2=cht.Shapes.AddShape(1,x,y,w,h) #矩形区域
shp2.Fill.PresetTextured(5) #水滴预设纹理
shp2.ScaleWidth(0.75, False) #宽度*0.75
shp2.ScaleHeight(1.75, False) #高度*1.75
缩放后的图形如图2-44所示。
图2-44 缩放以后的图形
图形翻转
图形的翻转也叫做图形的镜像变换,或对称变换。使用Shape对象的Flip方法实现图形的翻转。该方法是相对于水平对称轴或垂直对称轴作翻转的,它有一个参数,指定是水平翻转还是垂直翻转。水平翻转和垂直翻转对应的取值分别为0和1。
下面的例子创建一个矩形区域,为了便于对比,添加了木质纹理。然后对该区域进行水平翻转和垂直翻转操作。完整代码见:Samples->ch05 创建新图表->42 翻转变换->py.py。
#... 省略部分代码
cht.SeriesCollection().NewSeries() #新建序列
x=shape_x(cht,100)
y=shape_y(cht,200)
w=cht.PlotArea.InsideWidth/(ax1.MaximumScale-ax1.MinimumScale)*200
h=cht.PlotArea.InsideHeight/(ax2.MaximumScale-ax2.MinimumScale)*100
shp2=cht.Shapes.AddShape(1,x,y,w,h) #矩形区域
shp2.Fill.PresetTextured(22) #木纹预设纹理
shp2.Flip(0) #水平翻转
翻转前的图形如图2-45所示。图2-46为原图形水平翻转后的图形。
图2-45 原图形 图2-46 水平翻转
图2-47为垂直翻转后的结果,实现代码如下所示。完整代码见:Samples->ch05 创建新图表->43 翻转变换2->py.py。
图2-47 垂直翻转
x=shape_x(cht,100)
y=shape_y(cht,200)
w=cht.PlotArea.InsideWidth/(ax1.MaximumScale-ax1.MinimumScale)*200
h=cht.PlotArea.InsideHeight/(ax2.MaximumScale-ax2.MinimumScale)*100
shp2=cht.Shapes.AddShape(1,x,y,w,h) #矩形区域
shp2.Fill.PresetTextured(22) #木纹预设纹理
shp2.Flip(1) #竖直翻转