| 
 反正切(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设计与应用版块参加讨论
	       |