在PowerPoint中实现一个带撤销功能的3D模型旋转效果

分类: 编程 |
刘瑞祥
在PowerPoint里插入3D模型对象并且通过VBA控制其旋转的方法,想必大家已经会了吧?我想大家已经写出了设置3D对象绕各个轴正向和反向旋转的程序了。本文介绍一个技巧,来实现旋转的“撤销”功能,也就是说,当你不小心单击了某个旋转按钮后,即使你记不得误触了哪个按钮,也可以通过“撤销”按钮回到上一步,甚至可以多步撤销。类似这种“撤销”的功能在很多软件里都有,我们看如何用VBA来实现吧。
这种功能在其它语言里如何实现?大概需要某种“设计模式”或者堆栈一类的数据结构吧。然而VBA既没有求指针这种操作,也不是真正的面向对象,那我们就没有办法了吗?
办法当然总是有的,我先说说思路:
解决问题的关键在于我们要声明一个全局变量,也就是在全部语句之外(仍然是同一个模块里)声明一个字符型变量,用这个变量记录我们曾经按过哪些按钮,然后根据这个字符串实现撤销功能:
Private str_3D As String
接下来我们分三个部分进行讲解,本文需要的前置知识已经写过了(单击这里)。
一、设置3D模型对象的旋转
我们先来编写出正常的让3D模型对象旋转的语句,以X+和X-为例,语句如下:
Public Sub rX1()
End Sub
Public Sub rX2()
End Sub
(以上用的是Slides(1).Shapes(2),是因为这个3D对象位于幻灯片第1页,序号是2,同页序号1的是幻灯片页面标题)
对于Y+、Y-、Z+、Z-这些,我们的语句类似,但是有两点不同:
一是IncrementRotationX要改成IncrementRotationY和IncrementRotationZ;
二是前面的str_3D=str_3D & "A"及str_3D=str_3D &
"B"意思是在原来的str_3D变量后面加一个字母来标志刚刚按过哪个按钮,而在实现Y+、Y-、Z+、Z-对应功能的语句里,str_3D变量后自然不能再加A、B而应该加其它字母(本例依次是C、D、E、F)了。
二、实现撤销功能
Public Sub unDo()
End Sub
上一段程序首先判断字符串str_3D是否为空,如果是空的就说明已经恢复到幻灯片刚放映时的状态,程序结束。否则,取str_3D的最后一个字符,根据所取的这个字符判断当初是怎么旋转的,然后反过来操作即可。最后要把这个字符串去掉最后一位。
三、如何一步复位,兼谈属性和方法
细心的朋友已经看到前面的幻灯片页面里有个“初始化”按钮,怎么实现呢?难道需要一步步退回到最初的状态?这样执行起来会很慢的,但是我们可以这样编程:
Public Sub Init()
End Sub
大家可以看出,这里用到的是RotationX等“属性”,而非前面所用到的IncrementRotationX等“方法”。二者的区别是:属性一般被看作对象的一个值,可以进行设置,也可以进行读取,而方法被看作是对于对象的一个操作。比如某个现实中的学生,对他进行升留级操作是“方法”,而他所属的年级则是这个学生的“属性”;“迁户口”是一个方法,“户籍所在地”是一个属性。也就是说,方法名往往是动词,而属性名则是名词。要给某个属性赋值,可以用“对象名.属性(参数)=值”这样的语句,要把属性值赋给某个变量,则用“变量名=对象名.属性(参数)”这样的语句。而要使用方法,则只能采用"对象名.方法
参数"这样的语句。根据不同的属性和方法,其后的参数是可选的(本例里方法的后面有参数,属性的后面没有参数),但方法中的参数是不带括号的。
具体到本文的例子,就我个人的体会,IncrementRotationX方法和RotationX属性(对应的还有IncrementRotationY方法和和RotationY属性,以及IncrementRotationZ方法和RotationZ属性)还有两个区别:
首先,前者的参数是“变化量”,也就是“变化了多少”,后者是“变化到多少”;
其次,前者的坐标系是固定在3D模型对象上的,随着对象的旋转,坐标轴也在旋转,后者则是不变的。如果用物理上的概念来比喻,前者好像是“质心坐标系”,后者好像是“实验室坐标系”。至于我这么理解对不对,就请读者来检验了。如果大家有更好的解释,也欢迎留言。
PS:下面三个图,左图是该模型对象初始位置的视图,缺口都在右上靠前方,中间的是利用方法来实现的绕三个轴各转30度,右边是利用属性实现绕三个轴各转30度(中图和右图是对相同初始位置的3D对象分别执行后的效果):
Public Sub r1()
'执行效果如中图
End Sub
Public Sub r2()
'执行效果如右图
End Sub