2.5D测量仪器摆正里:设定过原点的平面方程求解,定义于平面,定于3D,旋转到点上面,旋转到线上面,摆正平面,怎么使用?

扫一扫,访问微社区
后使用快捷导航没有帐号?
签到成功!您今天第{todayrank}个签到,签到排名竞争激烈,记得每天都来签到哦!已连续签到:{constant}天,累计签到:{days}天
当前位置: &
查看: 1808|回复: 10
UGUI如何实现3D旋转特效?
4354/500排名<font color="#FF昨日变化10主题帖子积分
四处流浪, 积分 354, 距离下一级还需 146 积分
四处流浪, 积分 354, 距离下一级还需 146 积分
蛮牛币1007
在线时间52 小时
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
才可以下载或查看,没有帐号?
首先,我们先来对这个需求进行分析,从这篇文章的题目我们获得的一个关键信息是,希望通过某种方式实现3D滚动特效。因此我们首先要解决的一个是,我们应该采用方式来实现还是采用3D方式来实现这种界面效果。我们假定这里希望实现的效果如下图所示,我们可以注意到从这张图片的设计初衷来看,它更像是一种介绍产品特性的文案设计,我们这里仅仅是想通过这张图告诉大家,我们需要实现一个什么样的效果。软件开发过程中最大的成本在我看来主要来自沟通。因为事实上对普通用户而言技术并不重要,重要的是能否实现用户想要的功能,可是大部分情形是用户并不知道自己想要什么,除非你将实际的产品放到用户眼前甚至手中。好了,在对需求有了一个基本的印象以后,我们来思考如何实现这个需求。
具体来讲,我们有两种思路:
* 其一是采用真实的3D来制作,即我们通过一个圆柱体或者是多棱柱将图片”粘贴”在不同的面上,通过对圆柱体或者多棱柱进行旋转,然后以真实的3D的形式来呈现给用户。
* 其二是采用伪3D来制作,即我们通过在2D平面内对图片的层次进行合理化调整实现伪3D效果,配合插值、缩放等技巧来实现2D平面上的旋转,然后给用户一种视觉上的3D效果。
1.png (252.55 KB, 下载次数: 0)
10:20 上传
在这里我们选择采用伪3D来制作,为什么选择这种方案呢?因为它简单啊,哈哈。好了,我们现在将实际的需求进行抽象,我们会发现什么呢?我们注意到这本质上是一个曲线问题,我们可以将每个图片的中心用平滑的曲线连接起来,然后我们就得到了一条抛物线或者是圆锥曲线或者是贝塞尔曲线,在这里我们将其理解为什么样的曲线并不重要,因为这最终影响到的是曲线的平滑度问题,即细节上的调整。沿着这个思路,我们就意识到,这是一个根据曲线平均分布坐标点的过程,假设我们这里5张图片,并且曲线在中间位置可以找到一条垂直的对称轴,那么我们只需要将这5个点在水平方向上平均分布即可,事实上根据人类视觉的特点,这个距离应该是越来越小的,就像我们看到的一排并列的树木,越远的地方它们的间距会越来越小,而事实上它们的间距是一样的,根据这个特性我们可以表现出这种视觉上的纵深的感觉,在实际项目中它取决于美术设定和策划设定,我们这里就从最简单的情况开始分析。
好了,在解决了精灵放置的这个问题以后,我们接下来要解决的是什么呢?答案是精灵的层级,因为层级能够帮助我们营造一种视觉上的层次感和立体感,比如在跑酷游戏中我们常常使用视差滚动这种技术来表现3D效果,以及传统的斜45度瓦片地图来实现2.5D效果都是使用2D来模拟3D效果的经典案例。所以在这里除了确定每个精灵的放置位置以外,我们还有一个问题,如何对这些精灵进行排序,所幸的是在uGUI中我们可以通过SetSiblingIndex方法来设置一个精灵的深度,当每次通过按钮切换精灵的时候,我们都需要对所有精灵重新计算坐标和深度,而为了更好的视觉表现力,我们可以在切换的时候做一个简单的位移动画,至此我们就可以开始动手实现功能啦。
首先我们来搭建一个基本的场景,我们这里将一切浮华褪尽,我们可以看到在场景中有两个按钮,它们可以让我们当前选中的卡片,而界面底部的标签会显示我们当前选择的角色名称。虽然在这里采用触屏滑动的效果更好,可我们这里主要的目的是为了说明如何实现我们的思路,当引入这部分功能的设计以后,会增加大家在整体理解上的难度,所以我们这里以快速实现功能为主。注意到场景中的卡片此时都是相当“任性”地放置在界面上,这是因为我们稍后会采用算法计算每个卡片的实际位置,所以在这里完全可以忽略其“美观性”。
2.png (153.16 KB, 下载次数: 6)
10:21 上传
这里,我们设定场景的大小为800x460,那么在这种情况下,我们可以按照下面图中所示的曲线轨迹来构造一条曲线,考虑到椭圆方程比贝塞尔曲线更加简单易用,所以我们这里选择椭圆方程来作为场景中这些卡片排列的曲线方程。
3.png (250.83 KB, 下载次数: 0)
10:22 上传
此时以屏幕中心为原点构建平面直角坐标系,则这个椭圆是一个以长轴2A=400、短轴2B=640、中心在(0,320)上的椭圆。根据这个原理,我们可以将其代码实现分为三个步骤来实现。首先,我们将场景中的所有卡片存储在GameObject数组中,这里我们这里规定卡片的数目必须为奇数,然后我们从左到右依次计算每个卡片的位置和深度,这样就可以让卡片按照我们期望的方式进行排列啦。下面一起来看代码如何实现:
[C#] 纯文本查看 复制代码//初始化精灵数组
int childCount = transform.childC
//计算两侧精灵数目
halfSize = (childCount-1)/2;
//初始化精灵
sprites = new GameObject[childCount];
for(int i=0;i&childCi++)
sprites[i] = transform.GetChild(i).gameO
SetPosition(i);
SetDeepin(i);
这里sprites显然是一个GameObject[],因为卡片的数目为奇数个,所以halfSize是指中间位置卡片的索引,这里需要两个辅助方法,SetPosition和SetDeepin,从名字我们就知道这两个方法分别是设置卡片位置和设置卡片深度。当我们提到代码注释的时候,好多人以代码自注释为理解逃避注释,孰不知这建立在命名规范的基础上,如果你连这点基本的要求都做不到,我建议你还是多写点注释、少写点代码。好了,这两个方法的实现细节如下:
[C#] 纯文本查看 复制代码/// &summary&
/// 设置精灵位置
/// &/summary&
private void SetPosition(int index)
//计算第index个精灵的角度
float angle = 0.0f;
if (index & halfSize) {
angle = startAngle - (halfSize - index) * DeltaA
} else if (index & halfSize) {
angle = startAngle + (index - halfSize) * DeltaA
angle = startA
//计算第index个精灵的坐标
float x = A* Mathf.Cos((angle/180) * Mathf.PI) + Center.x;
float y = B* Mathf.Sin((angle/180) * Mathf.PI) + Center.y;
Vector3 v3 = Camera.main.WorldToScreenPoint(new Vector3(x,y,0));
v3 = Camera.main.ScreenToWorldPoint(v3);
Vector2 v2 = new Vector2(v3.x,v3.y);
sprites[index].GetComponent&RectTransform&().anchoredPosition = v2;
可以注意到,在这里我们根据精灵索引index和两侧精灵数目halfSize的关系,按照DeltaAngle这个增量来计算每个精灵实际的角度,在此基础上结合椭圆的参数方程,我们可以非常容易地计算出每个精灵实际的位置,这样就可以保证精灵中心都在椭圆曲线上。好了,接下来我们会遇到一个新的问题,这些精灵的层级应该是从中间位置向两边依次递减的,所以为了解决这个问题,我们还需要对每个精灵的层级进行计算,这部分代码的实现细节如下:
[C#] 纯文本查看 复制代码/// &summary&
/// 设置精灵深度
/// &/summary&
private void SetDeepin(int index)
//计算精灵深度
int deepin = 0;
if(index&halfSize){
}else if(index&halfSize){
deepin = sprites.Length-(1+index);
deepin = halfS
sprites[index].GetComponent&RectTransform&().SetSiblingIndex(deepin);
事实上,我在这里并不清楚SetSiblingIndex这个方法的真正作用:),可是它的确能够实现我们想要的功能。有时候在维护一个古老的项目的时候,可能你会在代码中看到各种有趣的注释,而这些注释中有相当一些都充满了一种“形而上学”的味道在里面,我们不知道这个世界为什么会是这样,可是看起来它们都运行地非常良好。或许这就是这个世界的奇妙之处,无论我们是否想要尝试打破这些规则,这个世界上总是有些我们难以理解的东西存在,可是存在即合理,不是吗?理性思维的缺陷在于想要为一切问题找到一个答案,所以这次苏格拉没有底,我们就感性一次又何妨呢,这个问题就让它没有答案吧!
现在,显然我们需要解决一个新的问题,就像上帝在我们关上一扇门的同时,会为我们开启一扇窗口。理论上任何问题都可以通过引入一个中间层来解决,而引入中间层的同时毫无疑问地引入了一个新的问题。在这里我们已经完成了让所有精灵按照椭圆曲线进行排布以及精灵的层级关系这两个问题,可是我们这是一个静态的过程啊,我们需要的是让它能够滚动起来,所以怎么解决这个问题呢?我们可以注意到的一点是,精灵的这种“滚动”效果,实际上是将数组中的第一个元素sprites[0]或者最后一个元素sprites[sprites.Length-1],依次和数组中的第i个元素进行交换。比如精灵整体向右侧“滚动”,我们只需要从第一个元素开始依次和最后一个元素进行交换就可以啦,所以这里的实现实际上是:
[C#] 纯文本查看 复制代码/// &summary&
/// 向后翻页
/// &/summary&
public void OnNext()
int length = sprites.L
for(int i=0;i&i++)
GameObject temp = sprites[i];
sprites[i] = sprites[length-1];
sprites[length-1] =
for(int i=0;i&i++)
SetPosition(i);
SetDeepin(i);
我们在对数组内的元素重新组织后,需要重新计算每个精灵的位置和深度。我这里在思考的一个问题是:精灵的位置和深度实际上是确定的,所以我们可以考虑将它们存储起来“复用”,这样可以减少每次的重复计算。其实,代码的优化和重构是一个需要时间来酝酿的过程,没有人能够在写代码的时候,就可以意识到代码中的瑕疵,而这种发现问题的眼光通常需要长时间的培养,这是我们之所以提倡不要过早优化的原因,除非你能够快速地找到代码中的优化点。好了,现在采用类似的思路,我们可以实现向前翻页的逻辑啦,这里的代码非常简单不再赘述。
本文介绍了一种基于曲线方程来构建伪3D效果的思路,主要借助椭圆的参数方程来计算精灵位置,使其实现按照椭圆曲线进行排布的效果,在此基础上配合层级调整、插值、缩放等技巧,在一定程度上可以实现2D平面内的伪3D旋转效果。因为博主身患拖延症晚期,所以这篇文章在拖延了很久以后,终于成功的成为了一个没有填完的坑,不过我相信掌握原理比获取代码更为重要,所以这篇文章更多的是希望能给大家提供相关思路。
每日推荐:
61446/1500排名<font color="#FF昨日变化8主题帖子积分
蛮牛粉丝, 积分 1446, 距离下一级还需 54 积分
蛮牛粉丝, 积分 1446, 距离下一级还需 54 积分
蛮牛币8245
在线时间566 小时
楼主能把工程也一起发下吗&&无限感激
每日推荐:
61138/1500排名<font color="#FF昨日变化1主题帖子积分
蛮牛粉丝, 积分 1138, 距离下一级还需 362 积分
蛮牛粉丝, 积分 1138, 距离下一级还需 362 积分
蛮牛币1849
在线时间225 小时
每日推荐:
71548/5000排名<font color="#FF昨日变化1主题帖子积分
日久生情, 积分 1548, 距离下一级还需 3452 积分
日久生情, 积分 1548, 距离下一级还需 3452 积分
蛮牛币3076
在线时间440 小时
文笔真好,娓娓道来,功力深厚!
每日推荐:
12/50主题帖子积分
注册看看, 积分 2, 距离下一级还需 48 积分
注册看看, 积分 2, 距离下一级还需 48 积分
在线时间1 小时
sprites = new GameObject[childCount];提示无法隐式转换。。。
每日推荐:
5834/1000排名<font color="#FF昨日变化3主题帖子积分
熟悉之中, 积分 834, 距离下一级还需 166 积分
熟悉之中, 积分 834, 距离下一级还需 166 积分
蛮牛币1302
在线时间258 小时
本帖最后由 wakingman 于
18:14 编辑
每日推荐:
5834/1000排名<font color="#FF昨日变化3主题帖子积分
熟悉之中, 积分 834, 距离下一级还需 166 积分
熟悉之中, 积分 834, 距离下一级还需 166 积分
蛮牛币1302
在线时间258 小时
赞!这里也有一个类似的,旋转效果
每日推荐:
263/150排名<font color="#FF昨日变化18主题帖子积分
初来乍到, 积分 63, 距离下一级还需 87 积分
初来乍到, 积分 63, 距离下一级还需 87 积分
在线时间20 小时
楼主知道那种具有惯性的滑动是怎么做出来的吗?
每日推荐:
5628/1000排名<font color="#FF昨日变化25主题帖子积分
熟悉之中, 积分 628, 距离下一级还需 372 积分
熟悉之中, 积分 628, 距离下一级还需 372 积分
蛮牛币1298
在线时间186 小时
必须赞个,给力
每日推荐:
5733/1000排名<font color="#FF昨日变化3主题帖子积分
熟悉之中, 积分 733, 距离下一级还需 267 积分
熟悉之中, 积分 733, 距离下一级还需 267 积分
在线时间204 小时
每日推荐:
3161/300排名<font color="#FF昨日变化130主题帖子积分
偶尔光临, 积分 161, 距离下一级还需 139 积分
偶尔光临, 积分 161, 距离下一级还需 139 积分
在线时间59 小时
哪里结合椭圆方程了
每日推荐:flash是一个二维动画制作软件,如何制作&#8220;三维&#8221;的效果呢?本文对此问题作一个很基础的探讨。
  请看演示:
http://www.flashempire.com/school/tutorview.php?id=143  一、三维坐标系转化成二维坐标系
  1、flash中的二维坐标系
  (1)、坐标的转换
  flash中场景左上角为(0,0),而在数学中是场景中心为(0,0),怎样把它转成数学中的坐标系呢?假设场景宽度:550,高度400。
  x=550/2+this._x;//x右移
  y=400/2-thix._y;//y下移
  如图1。
图1:转换后的坐标系
图2:角度、弧度的转换
  (2)、角度的转换
  flash中角度的计算:如图2hudu = Math.atan2(y, x);
// 利用公式tg a=y/x,计算a的值,flash中a是以
弧度表示的 ,我们要把它转换成角度,设圆的半
径r为1,整个弧长为2*pai*r,也就是说360度等于
2*pai弧度,所以转成角度的公式为:
jiaodu = hudu*180/Math.PI;
// 把弧度转换为角度,公式为:角度=弧度*180/3.14,3.14为pai
if (jiaodu&0) {
jiaodu = jiaodu+360;
/* 转换后的角度的范围从-180到180,
数学中的角度从0到360,所以小于0时加上360 */
  2、flash中的三维坐标系
  如图3,z轴表示一个物体离屏幕的远近,当物体的z轴位置增加时,物体朝远离屏幕的方向运动,当物体的z值减小时,物体朝接近屏幕的方向运动。
图3:三维坐标系
图4:二维与三维的点的关系
  3、三维坐标转换成二维坐标
  如图4,已知一个点(x,y,z),怎样确定该点屏幕上的位置呢?利用三角形相似的原理,可以得出下列结论:
  d/(d+z)=y1/y,推出:y1=d*y/(d+z),这公式就是浪子讲的经典的算法,可在二维平面上来表现空间上的点的位置。我们还可把它进一步把它简化。提出因子d/(d+z),用ratio(比率)表示,这个公式就变为
  ratio=d/(d+z);
  y1=ratio*x;同理可推出
  x1=ratio*y;
  终于写完第一步了,休息一下,到帝国论坛下了点毛毛雨,接着我们来看第二步
  二、控制物体的属性(大小,层次,透明度等)
  通过第一步的学习,我们就可建立一些三维的效果,但是还有很多不足之处,如远的物体和近的物体的大小一样,层次可能也不一样,怎么办呢?
  1、控制mc的大小
  在三维坐标中,当z值增大,也就是远离屏幕时,物体应越小,反之越大。我们怎么在flash中表示一个mc的大小呢?还记得上一步的ratio吗?现在就要用到这东东。当z增加时,ratio减少,因为在ratio中,z是作为分母的。反之,当z减少时,ratio增加。所以可用ratio来控制mc的大小。如下:
  mc1._xscale=mc._xscale*
  mc1._yscale=mc._yscale*
  2、控制mc的层次
  z值最大,物体应在最底层,最小,在最上层,所以我们可用一个很大的常数减去z值,用此值作为mc的层次。flash中,设置mc的层次用swapDepths,如下:
  mc.swapDepths(1000-z);//设置mc的层次
  3、控制mc的透明度
  远处的物体看上去模糊些,近处的物体清晰些,在flash中,可用_alpha来控制,方法和控制大小类似,不在介绍原理。如下:
  mc._alpha=100*
  4、控制mc的角度(旋转)
  这一步最难,也最好的东东。学习以后,你将能制作出非常cool的效果
  旋转有三种,x旋转:坐标x不变,y旋转:y不变,z旋转:z不变,我们先来推导z旋转。
  如下图:从点(x,y,0)转到(x1.y1.0),求点(x1.y1.0)
  利用数学中的正弦、余弦公式得出
  x1=r*cos(a+b),而cos(a+b)=sina*cosb+cosa*sinb [解释]
  推出:x1=r(cosa*cosb-sina*sinb)
  又因为x=r*cosa,y=r*sina
  所以x1=x*cosb-y*sinb
  同样推出:y1=y*cosb+x*sinb
  这就是z旋转的公式。用同样的方法可推出x旋转,y旋转的公式。总结如下:给定点:(x,y,z)
绕x轴旋转后的点(x1,y1,z1)
绕y轴旋转后的点(x2,y2,z2)
绕z轴旋转后的点(x3,y3,z3)
 x旋转(x不变)
y1=y*cosb-z*sinb
z1=z*cosb+y*sinb
y旋转(y不变)
x2=x*cosb-z1*sinb
z2=z1*cosb+x*sinb
z旋转(z不变)
x3=x2*cosb-y1*sinb
y3=y1*cosb+x2*sinb
  从以上公式可看出,在flash要实现旋转,先要求x轴的旋转点,再求y轴的旋转点,最后再求出z轴的旋转点。最后我们来一个x旋转的应用
  三、制作x轴旋转的正方体
  1、在场景中画一小球,并按F8转换为mc,实例命名为qiu。
  2、增加一层,命名为as,接下去我们来写as,如下:_root.onLoad = function() {
shumu = 8;
// 定义复制小球的数目
qiu._x = 6000;
// 让原始小球消失
for (var i = 0; i& i++) {
duplicateMovieClip("qiu", "qiu"+i, i);
// 复制小球,作为正方体的八个顶点
qiu_pos_x = new Array(100, 0, 0, 100, 100, 0, 0, 100);
qiu_pos_y = new Array(100, 100, 100, 100, 0, 0, 0, 0);
qiu_pos_z = new Array(50, 50, -50, -50, 50, 50, -50, -50);
// 从三维坐标中取正方体的8个顶点的坐标,保存在数组中
// 观察者与屏幕的距离
hutu = 0.001;
// 控制旋转的速度
b = hutu*180/Math.PI;
// 角、弧度的转换
_root.onEnterFrame = function() {
for (var i = 0; i& i++) {
x1 = qiu_pos_x[i];
y1 = qiu_pos_y[i]*Math.cos(b)-qiu_pos_z[i]*Math.sin(b);
z1 = qiu_pos_z[i]*Math.cos(b)+qiu_pos_y[i]*Math.sin(b);
// 按公式计算
qiu_pos_x[i] = x1;
qiu_pos_y[i] = y1;
qiu_pos_z[i] = z1;
// 更新数组元素
ratio = D/(D+z1);
perspective_x = x1*
perspective_y = y1*
// 按公式计算
_root["qiu"+i]._x = 275+perspective_x;
_root["qiu"+i]._y = 200-perspective_y;
// 设置球的坐标
_root["qiu"+i]._xscale = _root["qiu"+i]._yscale=50*
// 球的大小
_root["qiu"+i].swapDepths(10000-qiu_pos_z[i]);
// 球的层次
_root["qiu"+i]._alpha=100*//设置透明度
  3、按CTRL+Enter测试,一个简单的3D旋转就形成了。
http://www.7880.com/Info/Article-67a0ee40.html
效果演示:(用鼠标直接拖拽下面的物体)
  大家都知道三维的点都有3个坐标,但FLASH只是有二维的坐标,所以要在FLASH里实现&#8220;三维&#8221;的效果,就需要对点的坐标进行转化,简单的说,就是怎么把三维坐标转换成二维坐标。(其实,这并不是真正的三维,而是一种视觉欺骗,看上去像三维的就这么回事。所以上面三维带引号。)
  一、三维坐标系转化成二维坐标系
  (1)、坐标的转换
  flash中场景左上角为(0,0),而在数学中是场景中心为(0,0),怎样把它转成数学中的坐标系呢? 
  1.FLASH里的坐标视图
 x=Stage.width/2; // Stage.width是场景的宽;
 y=Stage.height/2; // Stage.height是场景的高;
  这样就把原坐标的原点移动了,场景的中心点,不过,Y轴还是向下,为正的。(这在后面做旋转时要注意的。)
  (2)、角度的转换
  flash中Math函数里的参数都要用到弧度,所以角度与弧度之间的转换是需要知道的。
  在flash as中,我们可以通过这样的表达式来进行转换:
hudu=jiaodu*Math.PI/180; / /把角度转换为弧度,公式为:弧度=角度 *3.14/180,3.14为paijiaodu=hudu*180/Math.PI; / /把弧度转换为角度,公式为:角度=弧度*180/3.14,3.14为pai(if (jiaodu&0) { jiaodu = jiaodu+360; }/* 转换后的角度的范围从-180到180, 数学中的角度从0到360,所以小于0时加上360 */)
  2、flash中的三维坐标系
  如图3,z轴表示一个物体离屏幕的远近,当物体的z轴位置增加时,物体朝远离屏幕的方向运动,当物体的z值减小时,物体朝接近屏幕的方向运动。
图3:三维坐标系
图4:二维与三维的点的关系
  3、三维坐标转换成二维坐标
  如图4,已知一个点(x,y,z),利用三角形相似的原理,可以得出下列结论:
  d/(d+z)=y1/y,推出:y1=d*y/(d+z),可在二维平面上来表现空间上的点的位置。进一步把它简化。提出因子d/(d+z),用ratio(比率)表示,这个公式就变为  ratio=d/(d+z);  y1=ratio*y;同理可推出  x1=ratio*x;
  二、控制物体的属性(大小,层次,透明度等)
  1、控制mc的大小
  在三维坐标中,当z值增大,也就是远离屏幕时,物体应越小,反之越大。
  我们可以用上满的ratio,当z增加时,ratio减少,因为在ratio中,z是作为分母的。反之,当z减少时,ratio增加。所以可用ratio来控制mc的大小。如下:
mc1._xscale=mc._xscale*mc1._yscale=mc._yscale*
  2、控制mc的层次
  z值最大,物体应在最底层,最小,在最上层,
  所以mc的层次可以有z组成,可以用很大的数减z,也可以让z除以负数,等等,这里方法比较灵活,也是做&#8221;三维&#8221;效果的关键,主要要在调试中确定适合设计的方法。flash中,设置mc的层次用swapDepths,如下:
mc.swapDepths(1000-z);//设置mc的层次mc.swapDepths(z/-4);
  3、控制mc的透明度
  远处的物体看上去模糊些,近处的物体清晰些,在flash中,可用_alpha来控制,方法和控制大小类似,不在介绍原理。如下:
mc._alpha=100*
  4、控制mc的角度(旋转)
  这一步最难,也最好的东东。学习以后,你将能制作出非常cool的效果  旋转有三种,x旋转:坐标x不变,y旋转:y不变,z旋转:z不变,我们先来推导z旋转。  如下图:从点(x,y,0)转到(x1.y1.0),求点(x1.y1.0)
  利用数学中的正弦、余弦公式得出
  x1=r*cos(a+b),而cos(a+b)=sina*cosb+cosa*sinb  推出:x1=r(cosa*cosb-sina*sinb)  又因为x=r*cosa,y=r*sina  所以x1=x*cosb-y*sinb  同样推出:y1=y*cosb+x*sinb
  这就是z旋转的公式。用同样的方法可推出x旋转,y旋转的公式。总结如下:
给定点:(x,y,z)绕x轴旋转后的点(x1,y1,z1)绕y轴旋转后的点(x2,y2,z2)绕z轴旋转后的点(x3,y3,z3)
 x旋转(x不变) x1=x y1=y*cosb-z*sinb z1=z*cosb+y*sinb
注:x旋转要注意,在FLASH中x1=x
 y1=y*cosb+z*sinb z1=z*cosb-y*sinb
是先加后减,因为FLASH里的Y轴是反的,箭头向下的。
 y旋转(y不变) x2=x*cosb-z1*sinb y2=y1 z2=z1*cosb+x*sinb z旋转(z不变) x3=x2*cosb-y1*sinb y3=y1*cosb+x2*sinb z3=z2
  从以上公式可看出,在flash要实现旋转,先要求x轴的旋转点,再求y轴的旋转点,最后再求出z轴的旋转点。最后我们来一个x旋转的应用
  三、制作x轴旋转的正方体
  1、在场景中画一小球,并按F8转换为mc,实例命名为qiu。
  2、增加一层,命名为as,接下去我们来写as,如下:
_root.onLoad = function() {shumu = 8;// 定义复制小球的数目qiu._x = 6000;// 让原始小球消失for (var i = 0; i& i++) {duplicateMovieClip("qiu", "qiu"+i, i);}// 复制小球,作为正方体的八个顶点qiu_pos_x = new Array(100, 0, 0, 100, 100, 0, 0, 100);qiu_pos_y = new Array(100, 100, 100, 100, 0, 0, 0, 0);qiu_pos_z = new Array(50, 50, -50, -50, 50, 50, -50, -50);// 从三维坐标中取正方体的8个顶点的坐标,保存在数组中D = 200;// 观察者与屏幕的距离hutu = 0.001;// 控制旋转的速度b = hutu*180/Math.PI;// 角、弧度的转换};_root.onEnterFrame = function() {for (var i = 0; i& i++) {x1 = qiu_pos_x[i];y1 = qiu_pos_y[i]*Math.cos(b)-qiu_pos_z[i]*Math.sin(b);z1 = qiu_pos_z[i]*Math.cos(b)+qiu_pos_y[i]*Math.sin(b);// 按公式计算qiu_pos_x[i] = x1;qiu_pos_y[i] = y1;qiu_pos_z[i] = z1;// 更新数组元素ratio = D/(D+z1);perspective_x = x1*perspective_y = y1*// 按公式计算_root["qiu"+i]._x = 275+perspective_x;_root["qiu"+i]._y = 200-perspective_y;/ 设置球的坐标_root["qiu"+i]._xscale = _root["qiu"+i]._yscale=50*// 球的大小_root["qiu"+i].swapDepths(10000-qiu_pos_z[i]);// 球的层次_root["qiu"+i]._alpha=100*//设置透明度}};
  3、按CTRL+Enter测试,一个简单的3D旋转就形成了。
  (至此为止,上面部分的教程很大程度上是参考《flash 3D 基础教程》(作者:zjs35 文章来源:flashempire 更新时间:)的,本人只在上面做了微小部分的修改,主要因为这篇对FLASH_3D效果的基础理论确实写的很好。修改的部分,是本人在学习之后,自己在实践练习中发现的一些需要注意的地方。)
  接下来将为大家解析一篇某人大虾写的立方体旋转的FLASH_AS,这位大虾是用纯AS写的,只要把代码全部复制到第一桢就可以了。我将做详细的解析!!!
//先给各项赋值,为后面的编辑作做准备 plane = [0, [0, 1, 2, 3, 4], [0, 5, 6, 7, 8], [0, 1, 2, 6, 5], [0, 2, 3, 7, 6], [0, 4, 3, 7, 8], [0, 1, 4, 8, 5]]; //给立方体的8个点都标上数,这里定义的数组是立方体的6个面,每个面上4个点,上面的数字就是哪四个点组成一个面,每组前面多个0,是为了下面做循环调用是方便,循环可以从i=1开始。大家自己可以根据上面的数组。画出它在三维坐标中的立体图形。另,第一&#20;,其实是[0,0,0,0,0]。dx = [0, 1, -1, -1, 1, 1, -1, -1, 1]; //这里是给8个点在三维坐标定义数组,竖着看,没一行就是一个点坐标的(x,y,z) ,另没组前面多个0,是为了下面做循环调用是方便,循环可以从i=1开始。dy = [0, 1, 1, 1, 1, -1, -1, -1, -1]; //dz = [0, 1, 1, -1, -1, 1, 1, -1, -1]; //colour=0x4499FF //这里定义的是立方体的颜色,其实,要6个面,每个面的颜色不同,就把这个colour定义成数组就可以了。同样前面加个0,也是上面的理由。//colour=[0,0x4499FF,0x6F13EC,0xF1F00E,0x6CE31C,0x26D9A3,0x808080];trans = Math.PI/180; //下面的弧度和角度的转换用cube_width = 100; //用于设定立方体的边的长度d = 400; //// 观察者与屏幕的距离num_planes = plane.length-1; //num_planes=6num_nodes = dx.length-1; //num_nodes=8num_nodes_per_plane = plane[1].length-1;//num_nodes_per_plane=4 xz_angle_inc = 0; //下面这4个定义对用鼠标控制旋转的速度有关,yz_angle_inc = 0; angle_inc_factor = .1; angle_dec_factor = .9; o_x = Stage.width/2; //把坐标原点移到屏幕中心o_y = Stage.height/2; node = new Array(); //定义新数组p_node = new Array(); //边长调整... 主要是求出8个点,在设定边长,情况下的坐标for (i=1; i&=num_ i++) { node[i] = new Object(); node[i].x = dx[i]*(cube_width/2); node[i].y = dy[i]*(cube_width/2); node[i].z = dz[i]*(cube_width/2); } for (i=1; i&=num_ i++) { //建立6个空白的影片剪辑,主要用于,每天影片剪辑,画一个立方体的面。_root.createEmptyMovieClip("plane"+i, i); } //版面的调整 下面的_root.onEnterFrame 会调用这里进行画立方体//对这里不理解的,看附录一的代码!function create_planes() { for (var i = 1; i&=num_ i++) { depth = 0; //设定深度初始值mc = _root["plane"+i]; //每个影片剪辑画一个立方体的一个面mc.clear(); //清除上次画的面,不用这句语句,可以看到面的连续旋转的会是什么轨迹,程序是怎么画的。不过,很难看。mc.beginFill(colour, 100); //设置立方体面的颜色,colour可以变数组colour[i],这样每个面可以画,不同的颜色。mc.lineStyle(3,0xFF);//设置立方体的棱的颜色mc.moveTo(p_node[plane[i][1]].x, p_node[plane[i][1]].y);//这里设定每个正方形面,开始画时的启始点。 for (j=num_nodes_per_ j&=1; j--) { //这里是连续读取4个点,画好一个正方形mc.lineTo(p_node[plane[i][j]].x, p_node[plane[i][j]].y); depth += node[plane[i][j]].z; //求每个面上4点旋转后,4个点的深度变化,并相加} depth /= -num_nodes_per_//注意除以负数,这样符合,FLASH的深度变化的远近情况 mc.swapDepths(depth); //有点的深度变化,来控制面的层次变化,如果没有这句,可以看到一个立方体在旋转是6个面的层次混乱。amount = depth/50*100+15;//用深度变化,在传值,这个参数主要用于下面的语句,下面的语句,用于立方体在旋转时,面的亮度的调整,符合一定的光照效果。 new Color(mc).setTransform({ra:amount, ga:amount, ba:amount}); //这句语句可以查看FLASH_AS语法参考,可以找到的。主要是对色彩的设置。} } //鼠标激发 _root.onMouseDown = function() { mouse_down = }; _root.onMouseUp = function() { mouse_down = }; _root.onEnterFrame = function() { if (mouse_down) { //判断,鼠标情况,对鼠标移动距离的相加,如果,没有&#8220;+=&#8221;而用&#8220;=&#8221;,这样鼠标每点一次,图象就跳回初始状态。可以自己实验看下效果,进行对比。xz_angle_inc += (_xmouse-old_mx)*angle_inc_ yz_angle_inc += (_ymouse-old_my)*angle_inc_ } for (i=1; i&=num_ i++) { sin_xz = Math.sin(xz_angle_inc*trans); //对弧度与角度的转化公式。cos_xz = Math.cos(xz_angle_inc*trans); sin_yz = Math.sin(yz_angle_inc*trans); cos_yz = Math.cos(yz_angle_inc*trans); rx1 = cos_xz*node[i].x-sin_xz*node[i].z; //这里就是上面的坐标转换公式里的,先按Y轴旋转,再按X轴旋转。ry1 = node[i].y; rz1 = cos_xz*node[i].z+sin_xz*node[i].x; rx2 = rx1; ry2 = cos_yz*ry1+sin_yz*rz1; rz2 = cos_yz*rz1-sin_yz*ry1; node[i].x = rx2; //这里是把每个旋转后,得到的先的坐标保存在变量里node[i].y = ry2; node[i].z = rz2; p_ratio = d/(d+node[i].z); //这个是上面d/(d+z)p_node[i] = new Object(); p_node[i].x = o_x+node[i].x*p_ //确定在屏幕上点的位置p_node[i].y = o_y-node[i].y*p_ } xz_angle_inc *= angle_dec_ //这个加速鼠标控制时的旋转速度yz_angle_inc *= angle_dec_ old_mx = _ //得到影片开始时的鼠标坐标old_my = _ create_planes(); //调用上面的函数,画出立方体}; //点评:本人只所以选择这个例子进行解析,主要是因为画立方体,是很常见的例子,也是3D里的一个基本的画法。另,这个例子的代码是很精练,简洁,再加上代码的前部分定义的一些值,利于以后做其他项目的开发,可以把这个程序改成一个类,适合自身以后,对画立方体时调用。同时,可以在这个程序基础上做进一步开发!比如,将好几个立方体叠起来,把图片放在立方体的面上,做一些旋转立体按钮等等,都是可以的。//附录一:/*function create_planes(){depth=0;plane1.clear();plane1.beginFill(0xAB548B,100);plane1.lineStyle(3,0xFF);plane1.moveTo(p_node[5].x,p_node[5].y);plane1.lineTo(p_node[8].x,p_node[8].y); plane1.lineTo(p_node[7].x,p_node[7].y);plane1.lineTo(p_node[6].x,p_node[6].y);plane1.lineTo(p_node[5].x,p_node[5].y);depth=node[8].z+node[7].z+node[6].z+node[5].z;depth=depth/(-4);plane1.swapDepths(depth);amount=depth/50*100+15;//new Color(plane1).setTransform({ra:amount,ga:amount,ba:amount,aa:amount});new Color(plane1).setTransform({ra:amount,ga:amount,ba:amount});depth=0;plane2.clear();plane2.beginFill(0x);plane2.lineStyle(3,0xFF);plane2.moveTo(p_node[1].x,p_node[1].y);plane2.lineTo(p_node[2].x,p_node[2].y);plane2.lineTo(p_node[3].x,p_node[3].y);plane2.lineTo(p_node[4].x,p_node[4].y);plane2.lineTo(p_node[1].x,p_node[1].y);depth=depth+node[4].z+node[3].z+node[2].z+node[1].z;depth=depth/(-4);plane2.swapDepths(depth);amount=depth/50*100+15;new Color(plane2).setTransform({ra:amount,ga:amount,ba:amount});depth=0;plane3.clear();plane3.beginFill(0x8A0FF0,100);plane3.lineStyle(3,0xFF);plane3.moveTo(p_node[1].x,p_node[1].y);plane3.lineTo(p_node[2].x,p_node[2].y);plane3.lineTo(p_node[6].x,p_node[6].y);plane3.lineTo(p_node[5].x,p_node[5].y);plane3.lineTo(p_node[1].x,p_node[1].y);depth=depth+node[1].z+node[2].z+node[6].z+node[5].z;depth=depth/(-4);plane3.swapDepths(depth);amount=depth/50*100+15;new Color(plane3).setTransform({ra:amount,ga:amount,ba:amount});depth=0;plane4.clear();plane4.beginFill(0xE61A48,100);plane4.lineStyle(3,0xFF); plane4.moveTo(p_node[2].x,p_node[2].y);plane4.lineTo(p_node[3].x,p_node[3].y);plane4.lineTo(p_node[7].x,p_node[7].y);plane4.lineTo(p_node[6].x,p_node[6].y);plane4.lineTo(p_node[2].x,p_node[2].y);depth=depth+node[2].z+node[3].z+node[7].z+node[6].z;depth=depth/(-4);plane4.swapDepths(depth);amount=depth/50*100+15;new Color(plane4).setTransform({ra:amount,ga:amount,ba:amount});depth=0;plane5.clear();plane5.beginFill(0x49B667,100);plane5.lineStyle(3,0xFF);plane5.moveTo(p_node[4].x,p_node[4].y);plane5.lineTo(p_node[3].x,p_node[3].y);plane5.lineTo(p_node[7].x,p_node[7].y);plane5.lineTo(p_node[8].x,p_node[8].y);plane5.lineTo(p_node[4].x,p_node[4].y);depth=depth+node[4].z+node[3].z+node[7].z+node[8].z;depth=depth/(-4);plane5.swapDepths(depth);amount=depth/50*100+15;new Color(plane5).setTransform({ra:amount,ga:amount,ba:amount});depth=0;plane6.clear();plane6.beginFill(0xDEB321,100);plane6.lineStyle(3,0xFF);plane6.moveTo(p_node[1].x,p_node[1].y);plane6.lineTo(p_node[5].x,p_node[5].y);plane6.lineTo(p_node[8].x,p_node[8].y);plane6.lineTo(p_node[4].x,p_node[4].y);plane6.lineTo(p_node[1].x,p_node[1].y);depth=depth+node[1].z+node[5].z+node[8].z+node[4].z;depth=depth/(-4);plane6.swapDepths(depth);amount=depth/50*100+15;new Color(plane6).setTransform({ra:amount,ga:amount,ba:amount});
简单的3D入手
//******************************************//月儿猫猫学习日志//AS3-3D单个mc旋转//******************************************
//舞台上剪辑名称为_mcstage.addEventListener(Event.ENTER_FRAME,onEF);stage.addEventListener(MouseEvent.CLICK,onChg);function onChg(evt){k++;}var k:uint = 0;function onEF(evt) {switch ( k%3) {case 0 :_mc.rotationX += 5;txt.text = "绕 X 轴旋转"case 1 :_mc.rotationY+=5;txt.text = "绕 Y 轴旋转"case 2 :_mc.rotationZ+=5;txt.text = "绕 Z 轴旋转"}}
经过测试可以看到:
1、rotationX 逐渐增加时 x 轴的旋转方向符合右手法则,用右手握住 x 轴,大拇指指向正方向
,其余手指弯曲,表示旋转方向,或者是rotationX 增大的方向。
2、rotationY 逐渐增加时 y 轴的旋转方向符合右手法则,用右手握住 y 轴,大拇指指向正方向
,其余手指弯曲,表示旋转方向,或者是rotationY 增大的方向。
3、rotationZ 逐渐增加时 z 轴的旋转方向符合右手法则,用右手握住 z 轴,大拇指指向正方向
,其余手指弯曲,表示旋转方向,或者是rotationZ 增大的方向。
4、连续多次点击之后,具体的旋转方向已经很难说清楚了,说明 _mc 发生旋转之后,其内部的3维坐
标系也同时进行旋转,因此,rotationX、rotationY、rotationZ 都是相对于已经旋转后的坐标系而言
的,换句话来说,影片剪辑内部的旋转度数只与它自身的坐标系有关,和外部的坐标系无关。[这里有演示]
测试代码如下:
stage.addEventListener(Event.ENTER_FRAME,onEF);stage.addEventListener(MouseEvent.CLICK,onChg);function onChg(evt){&k++;}var k:uint = 0;function onEF(evt) {&switch ( k%3) {&&case 0 :&&&_mc.rotationX += 5;&&&txt.text = "绕 X 轴旋转"&&&&&case 1 :&&&_mc.rotationY+=5;&&&txt.text = "绕 Y 轴旋转"&&&&&case 2 :&&&_mc.rotationZ+=5;&&&txt.text = "绕 Z 轴旋转"&&&&}}
经过测试可以看到:
1、rotationX 逐渐增加时 x 轴的旋转方向符合右手法则,用右手握住 x 轴,大拇指指向正方向,其余手指弯曲,表示旋转方向,或者是rotationX 增大的方向。
2、rotationY 逐渐增加时 y 轴的旋转方向符合右手法则,用右手握住 y 轴,大拇指指向正方向,其余手指弯曲,表示旋转方向,或者是rotationY 增大的方向。
3、rotationZ 逐渐增加时 z 轴的旋转方向符合右手法则,用右手握住 z 轴,大拇指指向正方向,其余手指弯曲,表示旋转方向,或者是rotationZ 增大的方向。
4、连续多次点击之后,具体的旋转方向已经很难说清楚了,说明 _mc 发生旋转之后,其内部的3维坐标系也同时进行旋转,因此,rotationX、rotationY、rotationZ 都是相对于已经旋转后的坐标系而言的,换句话来说,影片剪辑内部的旋转度数只与它自身的坐标系有关,和外部的坐标系无关。
  下面的例子,测试之后了解到,元件所处的层深与它的 Z 轴深度并不直接相关,但是可以根据 Z 坐标的大小进行排序,Z 值小的层深高一些,从而实现正确的层深。旋转度数也是一样,它只负责自身坐标系中的旋转,要在舞台空间中绕指定的位置进行旋转,就必须与某个角度值进行关联。相对来说,实现空间旋转更加方便了。
  z 轴的深度可以自动的决定元件缩放的大小,因此这部分不需要去考虑了。
  之前这个例子用 x y 坐标来计算时, x 坐标应用 cos 函数,y坐标应用sin函数,在这里发现 z 用cos ,x用sin 更准确一些,主要原因还是因为 z 的正方向是指向屏幕里面的缘故。
代码如下:
// 全局参数var numOfBalls:Number = 5;var radiusX:Number = 250;var radiusY:Number = 30;var centerX:Number = stage.stageWidth / 2;var centerY:Number = stage.stageHeight / 2;var speed:Number = 0.01;var arr = new Array();//创建对象for (var i=1; i&=numOfB i++) {&var t = this["m" + i];&&t.angle = i * ((Math.PI*2)/numOfBalls);&t.addEventListener(Event.ENTER_FRAME, mover);&arr.push( t );}//冒泡法排序function sortArr() {&var i,&var j = arr.length - 1;&while ( j&0 ) {&&bound =&&j = 0;&&for (i= 0; i&= bound -1; i++) {&&&if (arr[i + 1].z & arr[i].z) {&&&&swapChildrenAt(i,i+1);&&&&var xt = arr[i];&&&&arr[i] = arr[i + 1];&&&&arr[i + 1] =&&&&j =&&&}&&}&}}//摆放对象function mover(evt:Event) {&var t = evt.&t.x = Math.sin(t.angle) * radiusX + centerX;&t.y = Math.sin(t.angle) * radiusY + centerY;&t.z = Math.cos(t.angle) * radiusY * 8 + centerY;&t.rotationY = t.angle * 180/Math.PI;&&//var s = t.y /(centerY+radiusY);//求出缩放比   不再需要&//t.scaleX = t.scaleY =&     &&&&&&&&&&&&&&&&&&&&  不再需要&t.angle +=//设置移动速度&sortArr();}//鼠标侦听addEventListener(MouseEvent.MOUSE_MOVE, onMM);function onMM(evt:MouseEvent) {&speed = ( mouseX - centerX)/3000;}
AS3-3D多个mc旋转缩放,根据鼠标感应旋转缩放方向,已测试
//******************************************//月儿猫猫学习日志//AS3-3D多个mc旋转缩放,根据鼠标感应旋转缩放方向//******************************************
// 全局参数var numOfBalls:Number = 10;var radiusX:Number = 250;var radiusY:Number = 75;var centerX:Number = stage.stageWidth / 2;var centerY:Number = stage.stageHeight / 2;var speed:Number = 0.05;var arr = new Array();//创建对象//库中连接类名:Ballfor (var i=0; ivar t = new Ball();addChild(t);t.angle = i * ((Math.PI*2)/numOfBalls);t.addEventListener(Event.ENTER_FRAME, mover);arr.push( t );}//冒泡法排序function stArr() {var i,var j =arr.length - 1;while ( j&0 ) {bound =j = 0;for ( i= 0; i&= bound -1; i++) {if ( arr[i+1].y & arr[i].y ) {swapChildrenAt(i,i+1);var xt = arr[i];arr[i] = arr[i+1];arr[i+1] =j =}}}}//摆放对象function mover(evt:Event) {var t = evt.t.x = Math.cos( t.angle) * radiusX + centerX;t.y = Math.sin( t.angle) * radiusY + centerY;var s = t.y /(centerY+radiusY);//求出缩放比t.scaleX = t.scaleY =t.angle +=//设置移动速度stArr();}//鼠标侦听addEventListener(MouseEvent.MOUSE_MOVE, onMM);function onMM(evt:MouseEvent) {speed = ( mouseX - centerX)/1500;}
元件所处的层深与它的 Z 轴深度并不直接相关,但是可以根据 Z 坐标的大小进行排序,Z 值
小的层深高一些,从而实现正确的层深。旋转度数也是一样,它只负责自身坐标系中的旋转,要在舞台空
间中绕指定的位置进行旋转,就必须与某个角度值进行关联。相对来说,实现空间旋转更加方便了。
z 轴的深度可以自动的决定元件缩放的大小,因此这部分不需要去考虑了。
之前这个例子用 x y 坐标来计算时, x 坐标应用 cos 函数,y坐标应用sin函数,在这里发现 z 用
cos ,x用sin 更准确一些,主要原因还是因为 z 的正方向是指向屏幕里面的缘故。Flash CS4 和它相应的执行平台Flash 播放器10引进了使二维元素产生三维效果的功能如果你你身边的朋友说起视角变换,2.5D,或是3D投影,可能他们在讨论这个相关的支持。在这个小文章里,我会描述怎样来用程序熟练的操控3D空间里的元素。虽然我现在的描述看起来很复杂,但一旦你知道了怎样在Flash工作中完成视
角转换就会很简单。好了,我们就从怎样来在Flash中表现尺寸开始。
有三个坐标这三个坐标分别用x,y,z来表示,而在你最初开始做flash时你一定是只用x,y坐标了。利用Flash10播放器和Flash CS4,你仍可以创造和显示两个坐标轴的舞台。而现在你要做的就是依然用二维的舞台通过引起z轴来创造一个3维的场景忘掉你所有与Z轴有关的东西。把它当成另外的一条你可以把你的场景放上去的直线。在这个基础上当你把X,Y轴设定好了就会看到所发生的情况。而当你把Z的值设定了之后会发生什么情况?让我们来看几个例子。首先,看一下下面的这个图,看下当你把Z轴的值减小会发生什么。你的图形看起来变得更大。当你的Z的值增加时,情况刚好相反,你的图形看起来变得更小了。这个原因是,z的坐标一般是用来表示深度的。设想一下你在水里游泳,你潜下去多深是用Z轴的值来表示。如果你只是浮在水面上,那就相当于你的默认的深度,你的Z轴的值会是0.当你下潜的更深些的时候,你的Z轴的值就会增加。假如有人在岸上看你,就会发现,你下去的越深,你看起就会越小;而你离水面越近,你就看起来越大,代表你下潜的越浅。在所有以上的例子中,我对X,Y,Z都简要的说明了一下以使你对这三者的关系有一个更好的理解认识。可实际上,我们总是只看到X和Y轴就像南北和东西的表示。Z轴一般是垂直于我们电脑屏幕的,所以它的方向就像有一支箭正直射你。在大多的3D描述中,Z轴一般是用一个空心圆来表示(正如上图所示)或用一个中间有X的圆来表示。如果你要来表示方向这是很重要的。一个空心圆表示Z轴像一个箭头方向指向你。而一个中间有X的圆则表示Z轴箭头的方面刚好离你而去&#8212;这就像一支箭尾的四个羽毛正离你远去。明白了这些是不是很高兴?下面,我们先离开下主题,看一下可以让你熟练把你场景放在3D的空间里的代码。前面,你已经了解到各个坐标轴的作用。现在你要好好看下如何来运用Flash中的3D功能,我们来看下代码:Looking at the Code代码如下 :我们从一些简单的东西开始学习。通过坐标来设定一下你元素的位置,只是设置下你实例的X,Y,Z的属性值即可:movieClip.x = 20;movieClip.y = 50;movieClip.z = 100;上面的代码使你的影片剪辑移动到(20,50)的位置,同时深度为100.换句话说,你的影片剪辑在场景的右上角,而且变小了。另一个要完成的就是你希望这个平面可以绕任一个坐标来旋转。这个可以通过它的rotationX,rotationY, 和rotationZ三个属性来实现。movieClip.rotationX = 180;movieClip.rotationY = -45;movieClip.rotationZ = 90;下面的图来说明通过设置属性rotationX,rotationY,rotationZ会产生什么效果:旋转有点意思。在我所描述三个坐标轴的例子里,我已经声明Z轴是垂直你的电脑屏幕的,而在我的那个游泳的例子里,我说过,Z的值相当于你在水下有多深。而当你开始旋转X,Y和Z轴的时候,现实里的图形和你在场景里看到的就会不同,当你编写3D的程序时要记着。以上的就是了,只要设定以上我已经写出的六个属性,你就可以用以前的2D的元素来实现一些基本的3D效果。注意的是:尽管这些很Cool,但也有一些限制如果不借助于其它的已经存在的代码,或不用一些3D的库。All 3D Content Gets Converted into a Bitmap所有的3D 内容转换成位图Flash一个3D应用的不足之处是,3D场景中,不管你创造了什么样的元素来操控,它都会自动的转变为位图。所以一旦你应用了以下任一属性:z,rotationX,rotationY,rotationZ,Flash都会把元素转换成位图。一个完善的矢量图片,比如我一直在这里用的正方形,当你用默认的尺寸来看它时,它显示的常完美。而位图一旦你放大就会发现出现了曲带和模糊:就论视觉而言,你可以想象来操纵一个实际的位图图片,而不仅是矢量图,它表现的也一样的完美。相交是不可能的当图形在3D的空间时,有趣的冲撞相碰和交叉就成为可能。不兴的是,只是这还是用编程不能实现。例如,设想你有两个平行的长方形靠的很近,如下图:如果我要旋转蓝色的长方形,在现实里,就好像蓝色长方形的边缘部分会穿过与它临近的黄色的长方形。而实际上,发生的是好像黄色的根本不存在:这看起来很怪谈。这好像每个元素都在各自独立的Z轴和三维空间里,而不是在一个可以相碰的空间里Conclusion总结:I really hope this article helped you to understand conceptually how the x, y, and z axes are treated in Flash. The concepts are really the difficult part to fully wrap your head around. As you saw, the code itself is fairly straightforward. Even something like the example I showed on the first page is very easy to create, and I've provided the source file for that below://以上内容转自http://www.kirupa.com/developer/as3/intro_3d_as3_pg2.htm,并翻译过来的。如有不明白,可到网站上查看原文。
阅读(...) 评论()

我要回帖

更多关于 设一平面经过原点 的文章

 

随机推荐