反正切(Arctangent)
大家可能都猜到了,反正切简单地说就是正切函数的反函数。我们只要输入对边与邻边的比值,就可以得到相应的角度。 在 Flash 中有两个函数可计算反正切。第一个就是像前面介绍过的函数一样 Math.atan(ratio),只需提供对边与邻边的比例值。例如,前面学过30度角的正切值约为0.577。试一下:
trace(Math.atan(0.577) * 180 / Math.PI);
输出结果是一个近似30的数,不是非常直观易懂吗,为什么还需要另一个函数呢?下面请看图3-13,让它来回答:

图3-13 四个象限上的角
如图3-13所示,有四个不同的角:A,B,C,D。角A和B,在X轴上为正数,角C和D在X轴上为负数,同样,角A和D在Y轴上为负数,而角B和C在Y轴上为正数。因此,四个内角的比例分别为: A: –1/2 (–0.5) B: 1/2 (0.5) C: 1/ –2 (–0.5) D: –1/ –2 (0.5)
对边与邻边之比为0.5,输入Math.atan(0.5),并转换为角度制,结果大约为 26.57,那么究竟所指的是角B还是角D呢?两个比例都为0.5那样就无法分辨了,看似是个小问题,但对于日后的工作确有很大的影响。
下面有请 Math.atan2(y,x),这是 Flash 的另一个反正切函数,它比 Math.atan(ratio)要有用得多。实事上,只需要学会这个函数的用法就可以了,函数中包括两个参数:对边长度与邻边长度。有时常会误写成 x,y,请注意应该是 y,x。请看如下示例,输入 Math.atan2(1,2),然后记住这个结果: trace(Math.atan2(1, 2) * 180 / Math.PI); 输出结果为 26.565051177078,这正是角B的度数。下面再输入-1/-2(角D),再来试试:
trace(Math.atan2(-1, -2) * 180 / Math.PI);
出乎意料的结果–153.434948822922.为什么会这样?图3-14能给你解释。

图3-14 一个角的两种表示方法
从角D自身的底边开始,它确实为26.57度,但别忘了 Flash 的角度是从 X 轴的正半轴顺时针计算的。因此,从 Flash 的角度来衡量,则该角被视为-153.43度。下面就要开始在 Flash 中实践和应用三角学了。
旋转(Rotation)
我们想让一个影片剪辑或 Sprite 影片通过旋转来指向鼠标的位置,这将是个挑战。旋转(rotation)将成为我们工具箱中非常的工具,可以应用于游戏制作,鼠标追踪,界面设计等。
下面看一个示例。也可以根据以下步骤或打开文档类 RotateToMouse.as 和 Arrow.as(与本书中其它代码一同在 www.friendsofed.com 下载),这些是已写好的代码。首先,需要让物体旋转,它可以是一个在 Sprite 中绘制的箭头(Arrow)。事实上,如果我们要反复应用到这个箭头,可以把它制作成一个类:
package { import flash.display.Sprite; public class Arrow extends Sprite { public function Arrow() { init(); } public function init():void { graphics.lineStyle(1,0,1); graphics.beginFill(0xffff00); graphics.moveTo(-50,-25); graphics.lineTo(0,-25); graphics.lineTo(0,-50); graphics.lineTo(50,0); graphics.lineTo(0,50); graphics.lineTo(0,25); graphics.lineTo(-50,25); graphics.lineTo(-50,-25); graphics.endFill(); } } }
这里使用到了绘图 API (会在下一章介绍)来绘制箭头。无论何时需要一个箭头,只需写一句 new Arrow()即可,在图3-15中可看到显示结果。当绘制一些图像并进行旋转时,要注意它的指向,默让地指向右边,X的正半轴,这就是它旋转到0度时的状态。
我们先要创建一个Arrow类的实例,放致于舞台中心,并让它指向鼠标的方向,如图3-16。

图3-15 使用绘图API绘制的箭头
图3-16 下一次需要计算的值(图丢失)
很熟悉吗?与我们之前所讲的三角形相同,只不过多加入了鼠标与箭头的坐标。鼠标的位置只需使用 mouseX 和 mouseY 属性即可获得,同样,使用x,y属性,获得箭头的位置。使它们的值相减,就得到了两条边的长度。现在只需要使用 Math.atan2(dy,dx) 就可以求出夹角,然后把结果转换为角度制,最后让箭头的 rotation 属性等于这个夹角。代码如下:
var dx:Number = mouseX - arrow.x; var dy:Number = mouseY - arrow.y; var radians:Number = Math.atan2(dy, dx); arrow.rotation = radians * 180 / Math.PI;
当然,为了使之形成一个动画,还需要加入循环。如同前一章提到的,使用事件处理函数将会是最好的选择,请使用 enterFrame 事件。以下是这个完整的文档类:
package { import flash.display.Sprite; import flash.events.Event; public class RotateToMouse extends Sprite { private var arrow:Arrow; public function RotateToMouse() { init(); } private function init():void { arrow=new Arrow ; addChild(arrow); arrow.x=stage.stageWidth / 2; arrow.y=stage.stageHeight / 2; addEventListener(Event.ENTER_FRAME,onEnterFrame); } public function onEnterFrame(event:Event):void { var dx:Number=mouseX - arrow.x; var dy:Number=mouseY - arrow.y; var radians:Number=Math.atan2(dy,dx); arrow.rotation=radians * 180 / Math.PI; } } }
请确认 RotateToMouse.as 文件与 Arrow.as 文件在同一目录下,以 RotateToMouse 作为文档类,并为它创建 SWF。怎么样?就像施了魔法一样!假设如果我们没有 Math.atan2 这个函数,就要先通过,dy除以dx求出对边与邻边的比值,然后再写入 Math.atan 函数。下面用 Math.atan 函数来代替 Math.atan2 函数来试一下,代码如下:
var radians = Math.atan(dy / dx);
试试这种写法,马上就会发现问题。如果鼠标位于箭头的左侧,箭头不会指向鼠标,并与鼠标相背离。能说说为什么吗?回到有 A,B,C,D 四个角的图(图3-13),不要忘记角A和C拥有相同的比值,角B和D也是一样。这样一来, Flash 就无法知道所指的是哪个角,所以只能得到A与或角B。如果,鼠标处于D角区域,Flash 会回到B角区域并把箭头指向这个角度。毫无疑问,这时 Math.atan2 的好处就显示出来了,书中会经常用到这个函数。
出处:蓝色理想
责任编辑:bluehearts
上一页 三角学应用 [4] 下一页 三角学应用 [6]
◎进入论坛RIA设计与应用版块参加讨论
|