转 第三章 三角学应用(3)(as3.0)

圆和椭圆
     目前为止我们已经掌握了正弦波,下面再来看看它的兄弟,余弦波。与正弦波的形成相
同,只不过是使用余弦函数代替了正弦函数而已。 如果你还记得前面所说的正弦和余弦是怎
样一种相反关系的话,就能理解,它们只是波形都相同,只是所处位置不同了。图 3-19 为
余弦波图像:
转 <wbr>第三章 <wbr>三角学应用(3)(as3.0)
图 3-19 余弦波形
    可见,余弦图像中 0 度和 2pi 度(或 360 度)的值都为 1,从 1 开始经过 0,-1,0, 最后
回到 1。所以,它与正弦曲线相同,只不过位置发生了一点偏移。
圆形运动
    在执行物体移动的动画时,完全可以使用余弦来代替正弦。实际上,余弦和正弦协同工
作时,才能形成一个更加有用的功能:使物体沿圆形运动,如图 3-20。
转 <wbr>第三章 <wbr>三角学应用(3)(as3.0)

图 3-20 物体沿圆形运动时的几个点
      如图 3-20 所示,以图中的圆为例,盯住右侧的那直角条边(y),然后开始对它进行旋转,
我们发现这条边正在被倒置。  这条边的中心点就是圆心,而它的运动范围就是这个圆的半径。
就像在第一个正弦实验中一样,我们可以计算出这条边的长度:角的正弦值乘以半径。在这
里,使用正弦函数非常合适,当我们从侧面观察这个圆时,就可以算出 y 的长度——对边
的长度。如果把这个圆放倒,再来观察它,发现角是在向前向后或向左向右移动的。这时,
可以使用余弦函数计算出 x 的长度——邻边的长度。重要的一点是,两个的夹角都是相同
的,  而不像 Random.as 那个例子中使用不同的角度计算 x,y 坐标。  这里我们只需要记住用
正弦函数计算 y ,用余弦函数计算 x。下面请看 ActionScript 代码:
package {
  import flash.display.Sprite;
  import flash.events.Event;
  public class Circle extends Sprite {
   private var ball:Ball;
   private var angle:Number = 0;
   private var centerX:Number = 200;
   private var centerY:Number = 200;
   private var radius:Number = 50;
   private var speed:Number = .1;
   public function Circle() {
     init();
   }
   private function init():void {
     ball = new Ball();
     addChild(ball);
     ball.x = 0;
     addEventListener(Event.ENTER_FRAME, onEnterFrame);
   }
   public function onEnterFrame(event:Event):void {
     ball.x = centerX + Math.cos(angle) * radius;
     ball.y = centerY + Math.sin(angle) * radius;
     angle += speed;
   }
  }
}
      大家可以自己写这个例子,也可以打开 Circle.as 作为文档类。执行后发现,获得了
一个完美的圆。这段代码的精华就是使用余弦来确定 x 坐标,使用正弦来确定 y 坐标,你
应该对他们的关系非常了解了。在 Flash 中,只要提到 x ,你就应该马上想到余弦,并且
还能联想到 y 使用正弦。请在最后这段代码上多花些时间,它将是 ActionScript 动画工
具箱中最有用的工具之一。
椭圆运动
      想要获得一个椭圆该怎么办呢,其实很简单,问题就在于半径。如果让 x 和 y 运动的大
小相同,那么就得到一个圆。如果想得到一个椭圆形,我们只需要在计算 x 和 y 位置时使用
不同的半径值: radiusX 和 radiusY 。从严格的几何观点来看,使用这两个名称实在不怎
么好,但是它们确实非常简单易懂,也非常好记非常直观,所以我还是坚持使用这两个变量
名。下面看看它们是如何配合的,见 Oval.as:
package {
  import flash.display.Sprite;
  import flash.events.Event;
  public class Oval extends Sprite {
   private var ball:Ball;
   private var angle:Number = 0;
   private var centerX:Number = 200;
   private var centerY:Number = 200;
   private var radiusX:Number = 200;
   private var radiusY:Number = 100;
   private var speed:Number = .1;
   public function Oval() {
     init();
   }
   private function init():void {
     ball = new Ball();
     addChild(ball);
     ball.x = 0;
     addEventListener(Event.ENTER_FRAME, onEnterFrame);
   }
   public function onEnterFrame(event:Event):void {
     ball.x = centerX + Math.cos(angle) * radiusX;
     ball.y = centerY + Math.sin(angle) * radiusY;
     angle += speed;
   }
  }
}
                             意味着小球在距离 centerX 200 个像素内左右运动。 radiusY
      这里, radiusX 为 200,
为 100,意味着小球上下运动的范围只有 100 像素,这样就得到了一个不匀称的圆。
勾股定理
      最后,介绍一下勾股定理。虽然并不能算是三角学中正式的一部分,但是它与我们这个
学科还是有一些关系的,   并且还涉及到一个将来会经常使用的公式,所以在这里介绍它非常
合适。
      勾股定理是很久以前一个希腊人发明。 这个定理是说 A 的平方 + B 的平方 = C 的平方 ,
听起来好像是儿歌,如果大家之前学过这个定理,那么交流起来效果最好。
     深入探讨一下,另一种对该定理的叙述是:    直角三角形的两条直角边的平方和等于斜边
的平方,这句话真正说到点子上了。请看图 3-21 所示直角三角形。
                                                                                       2
两条直角边 A 和 B 长度为 3 和 4,斜边 C 长度为 5。毕达哥拉斯(Pythagoras)先生告诉我们 A
                                        2
+ B = C 。加入一些数字来检验一下,3 + 4 = 5 ,计算出 9 + 16 = 25。是的,非常正
确。
    如果大家已经知道了这个口决,那么勾股定理只不过就是一种有趣的关系。如果中知道
其中两条边的长度,那么勾股定理就派上用场了,可以用它很快地求出第三条边的长度。在
Flash 中,最常见的情况是我们只知道两条直角边的长度要求出斜边的长度。比如,求出两
点间的距离。
两点间距离
    假设在舞台上有两个 Sprite 影片,想要求出它们之间的距离。这是勾股定理在 Flash
中最为常见的应用。那么如何实现呢?已知两个 Sprite 的 x,y 坐标,把第一个影片的位
置称为 x1,y1,另一个影片的位置称为 x2,y2。

     如果你在本章中看了太多的直角三角形,那么很容易就把图 3-22 看成一个直角三角形,
而那条距离线(distance)就是三角形的斜边。在图 3-23 中,加入了这个三角形并填入了数
字。
    dx 为两个影片之间的 x 轴, 为它们之间的 y 轴。 x2 减 x1 就得到了 dx 的值: –
                              dy                  用                           58
50 = 8,同样,用 y2-y1 等于 6 得到 dy 的值。现在使用勾股定理,将 dx,dy 的平方相加,
就得到了距离(distance)的平方。
    换言之,62 + 82 = dist2,相当于 36 + 64(=100) = dist2。基础代数学讲过可以通
过开平方把它转化为 = dist。这样一来,就可以得出两个影片之间的距离为 10。
    现在,把它抽像成一个公式,这样的话,今后再遇到同样的问题,就可以直接使用这个
公式了。有两个位置 x1,y1 和 x2,y2,先计算出 x 的距离和 y 的距离,然后求出它们的
平方和,最后求出平方根,下面请看 ActionScript 写法:
dx = x2 – x1;
dy = y2 – y1;
dist = Math.sqrt(dx*dx + dy*dy);
    请特别注意这些代码,它们将是我们工具箱中又一个最好的工具。前两句是获得 x,y
轴上的距离。最后一句分为三个步骤:计算每个值的平方,把它们相加,求出平方根。下面
进行一下实践,文档类 Distance.as ,创建了两个 Sprite 影片,并随机摆放,最后计算
出它们之间的距离。
package {
 import flash.display.Sprite;
 public class Distance extends Sprite {
  public function Distance() {
    init();
  }
  private function init():void {
    var sprite1:Sprite = new Sprite();
    addChild(sprite1);
    sprite1.graphics.beginFill(0x000000);
    sprite1.graphics.drawRect(-2, -2, 4, 4);
    sprite1.graphics.endFill();
    sprite1.x = Math.random() * stage.stageWidth;
    sprite1.y = Math.random() * stage.stageHeight;
    var sprite2:Sprite = new Sprite();
    addChild(sprite2);
    sprite2.graphics.beginFill(0xff0000);
    sprite2.graphics.drawRect(-2, -2, 4, 4);
    sprite2.graphics.endFill();
    sprite2.x = Math.random() * stage.stageWidth;
     sprite2.y = Math.random() * stage.stageHeight;
     var dx:Number = sprite1.x - sprite2.x;
     var dy:Number = sprite1.y - sprite2.y;
     var dist:Number = Math.sqrt(dx * dx + dy * dy);
     trace(dist);
   }
  }
}
      编译执行这个动画后,就得到了两个影片之间的距离。每次执行,两个影片的位置
不同。不论它们处于什么位置,我们所获得的距离都是正数。有趣吧,但是还不够动态
下面这个示例,可以实时地获得影片的距离,请试一下这个文档类,MouseDistance.as
package {
  import flash.display.Sprite;
  import flash.events.MouseEvent;
  import flash.text.TextField;
  public class MouseDistance extends Sprite {
   private var sprite1:Sprite;
   private var textField:TextField;
   public function MouseDistance() {
     init();
   }
   private function init():void {
     sprite1 = new Sprite();
     addChild(sprite1);
     sprite1.graphics.beginFill(0x000000);
     sprite1.graphics.drawRect(-2, -2, 4, 4);
     sprite1.graphics.endFill();
     sprite1.x = stage.stageWidth / 2;
     sprite1.y = stage.stageHeight / 2;
     textField = new TextField();
     addChild(textField);
     stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
   }
   public function onMouseMove(event:MouseEvent):void {
     graphics.clear();
     graphics.lineStyle(1, 0, 1);
     graphics.moveTo(sprite1.x, sprite1.y);
     graphics.lineTo(mouseX, mouseY);
     var dx:Number = sprite1.x - mouseX;
     var dy:Number = sprite1.y - mouseY;
     var dist:Number = Math.sqrt(dx * dx + dy * dy);
     textField.text = dist.toString();
   }
  }
}
      在这里 dx 和 dx 的值是用 sprite1 的位置减去当前鼠标位置得出的,dist 的值放入一
个文本框中进行显示,    并在影片和鼠标之间绘制一条线(在下一章绘图 API 中会学到)。最后,
将所有这些代码放到处理函数 onMouseMove 中,每次鼠标移动时进行刷新。测试一下这个
文件,并移动鼠标,鼠标与影片剪辑之间会连接上一条线,并实时读取线的长度。
     后面的章节中,在学到碰撞检测时,我们会发现内置的碰撞检测(hit testing)方法存
在着先天不足,然后会看到使用勾股定理公式完成基于距离(distance-based)碰撞检测方
法。它还非常适合用于计算重力或弹力等,因为这些力的大小与两个物体之间的距离成正比。
本章重要公式
现在我们已经有了一个全新的工具箱,同时又多了不少工具,全部所有的工具将会在第 19
章列出,那么让我们看看现在都有了哪些工具。注意,这些公式非常地抽象和简化,里面不
包括数据类型和变量定义,在类中使用这些公式时,是否使用这些给出的句型取决于你。
基本三角函数的计算:
角的正弦值 = 对边 / 斜边
角的余弦值 = 邻边 / 斜边
角的正切值 = 对边 / 邻边
角度制与弧度制的相互转换:
弧度 = 角度 * Math.PI / 180
角度 = 弧度 * 180 / Math.PI
向鼠标旋转(或向某点旋转):
// substitute mouseX, mouseY with the x, y point to rotate to
dx = mouseX - sprite.x;
dy = mouseY - sprite.y;
sprite.rotation = Math.atan2(dy, dx) * 180 / Math.PI;
创建波形:
// assign value to x, y or other property of sprite or movie clip,
// use as drawing coordinates, etc.
public function onEnterFrame(event:Event){
value = center + Math.sin(angle) * range;
angle += speed;
}
创建圆形:
// assign position to x and y of sprite or movie clip,
// use as drawing coordinates, etc.
public function onEnterFrame(event:Event){
xposition = centerX + Math.cos(angle) * radius;
yposition = centerY + Math.sin(angle) * radius;
angle += speed;
}
创建椭圆:
// assign position to x and y of sprite or movie clip,
// use as drawing coordinates, etc.
public function onEnterFrame(event:Event){
xposition = centerX + Math.cos(angle) * radiusX;
yposition = centerY + Math.sin(angle) * radiusY;
angle += speed;
}
计算两点间距离:
// points are x1, y1 and x2, y2
// can be sprite / movie clip positions, mouse coordinates, etc.
dx = x2 – x1;
dy = y2 – y1;
dist = Math.sqrt(dx*dx + dy*dy);

 

这章知识尤为重要- -物体运动离不开这些基础

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值