高等物理:数值积分

1、欧拉积分

 1 package {
 2     import flash.display.Sprite;
 3     import flash.display.StageAlign;
 4     import flash.display.StageScaleMode;
 5     import flash.events.Event;
 6     import flash.geom.Point;
 7     import flash.utils.getTimer;
 8     public class Euler extends Sprite
 9     {
10         private var _ball:Sprite;
11         private var _position:Point;
12         private var _velocity:Point;
13         private var _gravity:Number = 32;
14         private var _bounce:Number = -0.6;
15         private var _oldTime:int;
16         private var _pixelsPerFoot:Number = 10;
17         
18         public function Euler()
19         {
20             stage.align = StageAlign.TOP_LEFT;
21             stage.scaleMode = StageScaleMode.NO_SCALE;
22             _ball = new Sprite();
23             _ball.graphics.beginFill(0xff0000);
24             _ball.graphics.drawCircle(0, 0, 20);
25             _ball.graphics.endFill();
26             _ball.x = 50;
27             _ball.y = 50;
28             addChild(_ball); 179
29             _velocity = new Point(10, 0);
30             _position = new Point( _ball.x / _pixelsPerFoot, _ball.y / _pixelsPerFoot );
31             _oldTime = getTimer();
32             addEventListener(Event.ENTER_FRAME, onEnterFrame);
33         }
34         private function onEnterFrame(event:Event):void
35         {
36             var time:int = getTimer();
37             var elapsed:Number = (time - _oldTime) / 1000;
38             _oldTime = time;
39             var accel:Point = acceleration(_position, _velocity);
40             _position.x += _velocity.x * elapsed;
41             _position.y += _velocity.y * elapsed;
42             _velocity.x += accel.x * elapsed;
43             _velocity.y += accel.y * elapsed;
44             // 检测如果对象超过边缘就弹回
45             if(_position.y > ( stage.stageHeight - 20 ) / _pixelsPerFoot )
46             {
47                 _position.y = ( stage.stageHeight - 20 ) / _pixelsPerFoot;
48                 _velocity.y *= _bounce;
49             }
50             if(_position.x > ( stage.stageWidth - 20 ) / _pixelsPerFoot )
51             {
52                 _position.x = ( stage.stageWidth - 20 ) / _pixelsPerFoot;
53                 _velocity.x *= _bounce
54             }
55             else if(_position.x < 20 / _pixelsPerFoot)
56             {
57                 _position.x = 20 / _pixelsPerFoot;
58                 _velocity.x *= _bounce;
59             }
60             _ball.x = _position.x * _pixelsPerFoot;
61             _ball.y = _position.y * _pixelsPerFoot;
62         }
63         private function acceleration(p:Point, v:Point):Point
64         {
65             return new Point(0, _gravity);
66         }
67     }
68 }
Euler

 

2、Runge-Kutta积分

RK2:计算出每段开始时和结束时的加速度和速度,然后取平均值。

首先,计算开始时的加速度,然后是位置和速度,这些和欧拉法是完全一致的。不过我们用新的变量来保存这些信息。

// position1是对象的当前位置

// velocity1是对象的当前速度

acceleration1 = acceleration(position1, velocity1)

position2 = position1 + velocity1 * time

velocity2 = velocity1 + acceleration1 * time

position2velocity2就是结束时对象的位置和速度。接下来求结束时的加速度:

acceleration2 = acceleration(position2, velocity2)

然后是RK2的关键一步,求两个状态下的平均速度和加速度:

position1 += (velocity1 + velocity2) / 2 * time

velocity1 += (acceleration1 + acceleration2) / 2 * time

开始时和结束时的平均速度乘以时间,得到改变的位移,加于当前位置,就是改变后的位置。同理加速度,就是改变后的速度。

 1 package {
 2     import flash.display.Sprite;
 3     import flash.display.StageAlign;
 4     import flash.display.StageScaleMode;
 5     import flash.events.Event;
 6     import flash.geom.Point;
 7     import flash.utils.getTimer;
 8     public class RK2 extends Sprite
 9     {
10         private var _ball:Sprite;
11         private var _position:Point;
12         private var _velocity:Point;
13         private var _gravity:Number = 32;
14         private var _bounce:Number = -0.6;
15         private var _oldTime:int;
16         private var _pixelsPerFoot:Number = 10;
17         public function RK2()
18         {
19             stage.align = StageAlign.TOP_LEFT;
20             stage.scaleMode = StageScaleMode.NO_SCALE;
21             _ball = new Sprite();
22             _ball.graphics.beginFill(0xff0000);
23             _ball.graphics.drawCircle(0, 0, 20);
24             _ball.graphics.endFill();
25             _ball.x = 50;
26             _ball.y = 50;
27             addChild(_ball);
28             _velocity = new Point(10, 0);
29             _position = new Point(_ball.x / _pixelsPerFoot, _ball.y / _pixelsPerFoot);
30             _oldTime = getTimer();
31             addEventListener(Event.ENTER_FRAME, onEnterFrame);
32         }
33         private function onEnterFrame(event:Event):void
34         {
35             var time:int = getTimer();
36             var elapsed:Number = (time - _oldTime) / 1000;
37             _oldTime = time;
38             var accel1:Point = acceleration(_position, _velocity);
39             var position2:Point = new Point();
40             position2.x = _position.x + _velocity.x * elapsed;
41             position2.y = _position.y + _velocity.y * elapsed;
42             var velocity2:Point = new Point();
43             velocity2.x = _velocity.x + accel1.x * elapsed; 183
44             velocity2.y = _velocity.y + accel1.x * elapsed;
45             var accel2:Point = acceleration(position2, velocity2);
46             _position.x += (_velocity.x + velocity2.x) / 2 * elapsed;
47             _position.y += (_velocity.y + velocity2.y) / 2 * elapsed;
48             _velocity.x += (accel1.x + accel2.x) / 2 * elapsed;
49             _velocity.y += (accel1.y + accel2.y) / 2 * elapsed;
50             if(_position.y > (stage.stageHeight - 20) / _pixelsPerFoot)
51             {
52                 _position.y = (stage.stageHeight - 20) / _pixelsPerFoot;
53                 _velocity.y *= _bounce;
54             }
55             if(_position.x > (stage.stageWidth - 20) / _pixelsPerFoot)
56             {
57                 _position.x = (stage.stageWidth - 20) / _pixelsPerFoot;
58                 _velocity.x *= _bounce
59             }
60             else if(_position.x < 20 / _pixelsPerFoot)
61             {
62                 _position.x = 20 / _pixelsPerFoot;
63                 _velocity.x *= _bounce;
64             }
65             _ball.x = _position.x * _pixelsPerFoot;
66             _ball.y = _position.y * _pixelsPerFoot;
67         }
68         private function acceleration(p:Point, v:Point):Point
69         {
70             return new Point(0, _gravity);
71         }
72     }
73 }
RK2

 

3、RK4:。如果人们提及“Runge-Kutta”,几乎总是讨论RK4。

和RK2比,我们要做差不多类似的事情,只是不再采用开始和结束端的信息,而是要用4处的信息。 

在RK4中,求平均值的方式有点不同。先让我们看看伪码,很长,所以名词我都用了简称。 

// pos1是对象的当前位置 

// vel1是对象的当前速度 

acc1 = acceleration(pos1, vel1) 

pos2 = pos1 + vel1 / 2 * time 

vel2 = vel1 + acc1 / 2 * time 

acc2 = acceleration(pos2, vel2) 

pos3 = pos1 + vel2 / 2 * time 

vel3 = vel1 + acc2 / 2 * time 

acc3 = acceleration(pos3, vel3) 

pos4 = pos1 + vel3 * time 

vel4 = vel1 + acc3 * time 

acc4 = acceleration(pos4, vel4) 

pos1 += (vel1 + vel2 * 2 + vel3 * 2 + vel4) / 6 * time 

vel1 += (acc1 + acc2 * 2 + acc3 * 2 + acc4) / 6 * time 

  注意,第一、第四步的求解和第二、第三步不同,在第二、第三步时候先除以了2,在最后求平均时又乘以了2。

 1 package {
 2     import flash.display.Sprite;
 3     import flash.display.StageAlign;
 4     import flash.display.StageScaleMode;
 5     import flash.events.Event;
 6     import flash.geom.Point;
 7     import flash.utils.getTimer;
 8     public class RK4 extends Sprite
 9     {
10         private var _ball:Sprite;
11         private var _position:Point;
12         private var _velocity:Point;
13         private var _gravity:Number = 32;
14         private var _bounce:Number = -0.6;
15         private var _oldTime:int;
16         private var _pixelsPerFoot:Number = 10;
17         public function RK4()
18         {
19             stage.align = StageAlign.TOP_LEFT;
20             stage.scaleMode = StageScaleMode.NO_SCALE;
21             _ball = new Sprite();
22             _ball.graphics.beginFill(0xff0000);
23             _ball.graphics.drawCircle(0, 0, 20);
24             _ball.graphics.endFill();
25             _ball.x = 50;
26             _ball.y = 50;
27             addChild(_ball);
28             _velocity = new Point(10, 0);
29             185
30             _position = new Point(_ball.x / _pixelsPerFoot, _ball.y / _pixelsPerFoot);
31             _oldTime = getTimer();
32             addEventListener(Event.ENTER_FRAME, onEnterFrame);
33         }
34         private function onEnterFrame(event:Event):void
35         {
36             var time:int = getTimer();
37             var elapsed:Number = (time - _oldTime) / 1000;
38             _oldTime = time;
39             var accel1:Point = acceleration(_position, _velocity);
40             var position2:Point = new Point();
41             position2.x = _position.x + _velocity.x / 2 * elapsed;
42             position2.y = _position.y + _velocity.y / 2 * elapsed;
43             var velocity2:Point = new Point();
44             velocity2.x = _velocity.x + accel1.x / 2 * elapsed;
45             velocity2.y = _velocity.y + accel1.x / 2 * elapsed;
46             var accel2:Point = acceleration(position2, velocity2);
47             var position3:Point = new Point();
48             position3.x = _position.x + velocity2.x / 2 * elapsed;
49             position3.y = _position.y + velocity2.y / 2 * elapsed;
50             var velocity3:Point = new Point();
51             velocity3.x = _velocity.x + accel2.x / 2 * elapsed;
52             velocity3.y = _velocity.y + accel2.y / 2 * elapsed;
53             var accel3:Point = acceleration(position3, velocity3);
54             var position4:Point = new Point();
55             position4.x = _position.x + velocity3.x * elapsed;
56             position4.y = _position.y + velocity3.y * elapsed;
57             var velocity4:Point = new Point();
58             velocity4.x = _velocity.x + accel3.x * elapsed;
59             velocity4.y = _velocity.y + accel3.y * elapsed;
60             var accel4:Point = acceleration(position4, velocity4);
61             _position.x += (_velocity.x + 2 * velocity2.x + 2 * velocity3.x + velocity4.x) / 6 * elapsed;
62             _position.y += (_velocity.y + 2 * velocity2.y + 2 * velocity3.y + velocity4.y) / 6 * elapsed;
63             _velocity.x += (accel1.x + 2 * accel2.x + 2 * accel3.x + accel4.x) / 6 * elapsed;
64             _velocity.y += (accel1.y + 2 * accel2.y + 2 * accel3.y + accel4.y) / 6 * elapsed;
65             if(_position.y > (stage.stageHeight - 20) / _pixelsPerFoot)
66             {
67                 _position.y = (stage.stageHeight - 20) / _pixelsPerFoot;
68                 186
69                 _velocity.y *= _bounce;
70             }
71             if(_position.x > (stage.stageWidth - 20) / _pixelsPerFoot)
72             {
73                 _position.x = (stage.stageWidth - 20) / _pixelsPerFoot;
74                 _velocity.x *= _bounce
75             }
76             else if(_position.x < 20 / _pixelsPerFoot)
77             {
78                 _position.x = 20 / _pixelsPerFoot;
79                 _velocity.x *= _bounce;
80             }
81             _ball.x = _position.x * _pixelsPerFoot;
82             _ball.y = _position.y * _pixelsPerFoot;
83         }
84         private function acceleration(p:Point, v:Point):Point
85         {
86             return new Point(0, _gravity);
87         }
88     }
89 }
RK4

 

 3、Verlet积分法:

      Verlet积分法最初作为模拟分子运动来开发的。

      Verlet积分法的优势不像Runge-Kutta那样以超精确为主。

      Verlet积分法最突出的一点是不用保存对象的速度,取而代之的是保存对象的位置。

 

Verlet点:

创建一个VerletPoint类,它封装了一个点所拥有的Verlet积分法的所有行为。是点,就需要x和y属性,还有old x和old y以及一个update函数。update函数是告诉点之前在哪里,然后该去哪里,并使用什么样的速度。然后保存当前位置为之前位置,以便下次使用。基本逻辑如下: 

temp = currentPosition 

velocity = currentPosition - oldPosition 

currentPosition += velocity 

oldPosition = temp 

因为当前位置会被改变,所以需要先把当前位置保存在一个临时变量里。 

然后计算出速度,并加于当前位置下,最后把之前保存的当前位置作为之前位置保留下来。 

 1 package
 2 {
 3     import flash.display.Graphics;
 4     import flash.geom.Rectangle;
 5     public class VerletPoint
 6     {
 7         public var x:Number;
 8         public var y:Number;
 9         private var _oldX:Number;
10         private var _oldY:Number;
11         public function VerletPoint(x:Number, y:Number)
12         {
13             setPosition(x, y);
14             
15         }
16         public function update():void
17         {
18             var tempX:Number = x;
19             var tempY:Number = y;
20             x += vx;
21             y += vy;
22             _oldX = tempX;
23             _oldY = tempY;
24         }
25         public function setPosition(x:Number, y:Number):void
26         {
27             this.x = _oldX = x;
28             this.y = _oldY = y;
29         }
30         public function constrain(rect:Rectangle):void
31         {
32             x = Math.max(rect.left, Math.min(rect.right, x));
33             y = Math.max(rect.top, Math.min(rect.bottom, y));
34         }
35         public function set vx(value:Number):void
36         {
37             _oldX = x - value;
38         }
39         public function get vx():Number
40         { 
41             return x - _oldX;
42         }
43         public function set vy(value:Number):void
44         {
45             _oldY = y - value;
46         }
47         public function get vy():Number
48         {
49             return y - _oldY;
50         }
51         public function render(g:Graphics):void
52         {
53             g.beginFill(0);
54             g.drawCircle(x, y, 4);
55             g.endFill();
56         }
57     }
58 }
VerletPoint

 

   vx和vy采用getter/setter方式,因为Verlet积分法是不保存速度的。其实getter/setter方式并不保存任何信息。当设置vx时,_oldX等于当前x减去给定的值,这就好像在说速度的由来,而类似getter得到的也是位置相减的结果。所以并没有去保存一个叫速度的信息。

 1 package {
 2     import flash.display.Sprite;
 3     import flash.display.StageAlign;
 4     import flash.display.StageScaleMode;
 5     import flash.events.Event;
 6     import flash.geom.Rectangle;
 7     public class VerletPointTest extends Sprite
 8     {
 9         private var _point:VerletPoint;
10         public function VerletPointTest()
11         {
12             stage.align = StageAlign.TOP_LEFT;
13             stage.scaleMode = StageScaleMode.NO_SCALE;
14             _point = new VerletPoint(100, 100);
15             
16             //尽管通过vx、vy来改变速度概念上更清晰,
17             //但是用位置却有着更高的效率,因为这么做只需改变一个变量。
18             //如果有众多粒子进行交互,效率问题是首先要考虑的。
19             //_point.vx = 1;
20             _point.x += 1;
21             //_point.vy = 1;
22             _point.y += 1;
23             
24             addEventListener(Event.ENTER_FRAME, onEnterFrame);
25         }
26         private function onEnterFrame(event:Event):void
27         {
28             _point.update();
29             graphics.clear();
30             _point.render(graphics);
31         }
32     }
33 }
VerletPointTest

 点的约束:把点控制在场景内。

    创建了一个场景大小的矩形(你可以定义任意大小的矩形),然后在调用update之前,把它作为参数传给constrain函数。

public function constrain(rect:Rectangle):void
        {
            x = Math.max(rect.left, Math.min(rect.right, x));
            y = Math.max(rect.top, Math.min(rect.bottom, y));
        }

 Verlet线段:

    一个线段确定两个点。线段有length属性,它代表着两个点之间的距离大小。如果两点之间的距离和length有差异,就适当的贴近或者远离。

 1 package
 2 {
 3     import flash.display.Graphics;
 4     public class VerletStick
 5     {
 6         private var _pointA:VerletPoint;
 7         private var _pointB:VerletPoint;
 8         private var _length:Number;
 9         public function VerletStick(pointA:VerletPoint, pointB:VerletPoint, length:Number = -1)
10         {
11             _pointA = pointA;
12             _pointB = pointB;
13             if(length == -1)
14             {
15                 var dx:Number = _pointA.x - _pointB.x;
16                 var dy:Number = _pointA.y - _pointB.y;
17                 _length = Math.sqrt(dx * dx + dy * dy);
18             }
19             else
20             {
21                 _length = length;
22             }
23         }
24         public function update():void
25         {
26             var dx:Number = _pointB.x - _pointA.x;
27             var dy:Number = _pointB.y - _pointA.y;
28             var dist:Number = Math.sqrt(dx * dx + dy * dy);
29             var diff:Number = _length - dist;
30             var offsetX:Number = (diff * dx / dist) / 2;
31             var offsetY:Number = (diff * dy / dist) / 2;
32             
33             // 第一个点减去x、y偏移量的一半,第二个点加上x、y偏移量的一半。这样做
34             // 让两个点都有反应,并保证之间的距离和length一致。
35             _pointA.x -= offsetX;
36             _pointA.y -= offsetY;
37             _pointB.x += offsetX;
38             _pointB.y += offsetY;
39         }
40         public function render(g:Graphics):void
41         {
42             g.lineStyle(0);
43             g.moveTo(_pointA.x, _pointA.y);
44             g.lineTo(_pointB.x, _pointB.y);
45         }
46     }
47 }
VerletStick

 

 1 package {
 2     import flash.display.Sprite;
 3     import flash.display.StageAlign;
 4     import flash.display.StageScaleMode;
 5     import flash.events.Event;
 6     import flash.geom.Rectangle;
 7     public class VerletStickTest extends Sprite
 8     {
 9         private var _pointA:VerletPoint;
10         private var _pointB:VerletPoint;
11         private var _stick:VerletStick;
12         private var _stageRect:Rectangle;
13         public function VerletStickTest()
14         {
15             stage.align = StageAlign.TOP_LEFT;
16             stage.scaleMode = StageScaleMode.NO_SCALE;
17             _stageRect = new Rectangle(0, 0, stage.stageWidth,stage.stageHeight);
18             _pointA = new VerletPoint(100, 100);
19             _pointB = new VerletPoint(105, 200);
20             _stick = new VerletStick(_pointA, _pointB);
21             addEventListener(Event.ENTER_FRAME, onEnterFrame);
22         }
23         
24         // 看起来好像有弹性一样
25         /*private function onEnterFrame(event:Event):void
26         {
27             _pointA.y += .5;
28             _pointA.update();
29             _pointA.constrain(_stageRect);
30             _pointB.y += .5;
31             _pointB.update();
32             _pointB.constrain(_stageRect);
33             _stick.update();
34             graphics.clear();
35             _pointA.render(graphics);
36             _pointB.render(graphics);
37             _stick.render(graphics);
38         }*/
39         
40         
41         private function onEnterFrame(event:Event):void
42         {
43             _pointA.y += .5;
44             _pointA.update();
45             _pointB.y += .5;
46             _pointB.update();
47             
48             // 线段的update函数在试着推进两个点时,
49             // 接触到矩形底部的点又被强制拉了回来。
50             // 同时作用的两个反作用力,导致两个点稍稍向上弹起以适应所有的约束条件。
51             // 我们就需要多调用几次点的
52             // constrain函数和线段的update函数,让它们尽快适应条件,来去掉这个弹性
53             for(var i:int = 0; i < 5; i++)
54             {
55                 _pointA.constrain(_stageRect);
56                 _pointB.constrain(_stageRect);
57                 _stick.update();
58             }
59             graphics.clear();
60             _pointA.render(graphics);
61             _pointB.render(graphics);
62             _stick.render(graphics);
63         }
64         
65     }
66 }
VerletStickTest

 

Verlet结构体:

    一个Verlet结构体由多条线段组成。最简单的实心结构体是三角形。

 1 package {
 2     import flash.display.Sprite;
 3     import flash.display.StageAlign;
 4     import flash.display.StageScaleMode;
 5     import flash.events.Event;
 6     import flash.geom.Rectangle;
 7     public class Triangle extends Sprite
 8     {
 9         private var _pointA:VerletPoint;
10         private var _pointB:VerletPoint;
11         private var _pointC:VerletPoint;
12         private var _stickA:VerletStick;
13         private var _stickB:VerletStick;
14         private var _stickC:VerletStick;
15         private var _stageRect:Rectangle;
16         public function Triangle()
17         {
18             stage.align = StageAlign.TOP_LEFT;
19             stage.scaleMode = StageScaleMode.NO_SCALE;
20             _stageRect = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight);
21             _pointA = new VerletPoint(100, 100);
22             _pointB = new VerletPoint(200, 100);
23             _pointC = new VerletPoint(150, 200);
24             _stickA = new VerletStick(_pointA, _pointB);
25             _stickB = new VerletStick(_pointB, _pointC);
26             _stickC = new VerletStick(_pointC, _pointA);
27             addEventListener(Event.ENTER_FRAME, onEnterFrame);
28         }
29         private function onEnterFrame(event:Event):void
30         {
31             _pointA.y += .5;
32             _pointA.update();
33             _pointB.y += .5;
34             _pointB.update();
35             _pointC.y += .5;
36             _pointC.update();
37             
38             // 加大循环次数可提高钢性
39             for(var i:int = 0; i < 1; i++)
40             {
41                 _pointA.constrain(_stageRect);
42                 _pointB.constrain(_stageRect);
43                 _pointC.constrain(_stageRect);
44                 _stickA.update();
45                 _stickB.update();
46                 _stickC.update();
47             }
48             graphics.clear();
49             _pointA.render(graphics);
50             _pointB.render(graphics);
51             _pointC.render(graphics);
52             _stickA.render(graphics);
53             _stickB.render(graphics);
54             _stickC.render(graphics);
55         }
56     }
57 }
Triangle
 1 package {
 2 import flash.display.Sprite;
 3 import flash.display.StageAlign;
 4 import flash.display.StageScaleMode;
 5 import flash.events.Event;
 6 import flash.geom.Rectangle;
 7 public class Square extends Sprite
 8 {
 9 private var _points:Array;
10 private var _sticks:Array;
11 private var _stageRect:Rectangle;
12 public function Square()
13 {
14 stage.align = StageAlign.TOP_LEFT;
15 stage.scaleMode = StageScaleMode.NO_SCALE;
16 _stageRect = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight);
17 _points = new Array();
18 _sticks = new Array();
19 var pointA:VerletPoint = makePoint(100, 100);
20 pointA.vx = 10;
21 var pointB:VerletPoint = makePoint(200, 100);
22 var pointC:VerletPoint = makePoint(200, 200);
23 var pointD:VerletPoint = makePoint(100, 200);
24 makeStick(pointA, pointB);
25 makeStick(pointB, pointC);
26 makeStick(pointC, pointD);
27 makeStick(pointD, pointA);
28 makeStick(pointA, pointC);
29 addEventListener(Event.ENTER_FRAME, onEnterFrame);
30 } 200
31 private function onEnterFrame(event:Event):void
32 {
33 updatePoints();
34 for(var i:int = 0; i < 1; i++)
35 {
36 constrainPoints();
37 updateSticks();
38 }
39 graphics.clear();
40 renderPoints();
41 renderSticks();
42 }
43 private function makePoint(xpos:Number, ypos:Number):VerletPoint
44 {
45 var point:VerletPoint = new VerletPoint(xpos, ypos);
46 _points.push(point);
47 return point;
48 }
49 private function makeStick(pointA:VerletPoint, pointB:VerletPoint, length:Number = -1):VerletStick
50 {
51 var stick:VerletStick = new VerletStick(pointA, pointB, length);
52 _sticks.push(stick);
53 return stick;
54 }
55 private function updatePoints():void
56 {
57 for(var i:int = 0; i < _points.length; i++)
58 {
59 var point:VerletPoint = _points[i] as VerletPoint;
60 point.y += .5;
61 point.update();
62 }
63 }
64 private function constrainPoints():void
65 {
66 for(var i:int = 0; i < _points.length; i++)
67 {
68 var point:VerletPoint = _points[i] as VerletPoint;
69 point.constrain(_stageRect);
70 }
71 }
72 private function updateSticks():void
73 {
74 for(var i:int = 0; i < _sticks.length; i++)
75 201
76 {
77 var stick:VerletStick = _sticks[i] as VerletStick;
78 stick.update();
79 }
80 }
81 private function renderPoints():void
82 {
83 for(var i:int = 0; i < _points.length; i++)
84 {
85 var point:VerletPoint = _points[i] as VerletPoint;
86 point.render(graphics);
87 }
88 }
89 private function renderSticks():void
90 {
91 for(var i:int = 0; i < _sticks.length; i++)
92 {
93 var stick:VerletStick = _sticks[i] as VerletStick;
94 stick.render(graphics);
95 }
96 }
97 }
98 }
Square

 

拉链式结构:

    这种结构由两种结构共享与一点所组成。它们可以自由移动,但都围绕在同一枢轴处。这里将介绍如何制作一个单摆器。

 1 public function Hinge()
 2         {
 3             stage.align = StageAlign.TOP_LEFT;
 4             stage.scaleMode = StageScaleMode.NO_SCALE;
 5             _stageRect = new Rectangle(0, 0, stage.stageWidth,stage.stageHeight);
 6             _points = new Array();
 7             _sticks = new Array();
 8             // 根基
 9             var pointA:VerletPoint = makePoint(stage.stageWidth / 2,stage.stageHeight - 500);
10             var pointB:VerletPoint = makePoint(0, stage.stageHeight);
11             var pointC:VerletPoint = makePoint(stage.stageWidth,stage.stageHeight);
12             // 臂摆
13             var pointD:VerletPoint = makePoint(stage.stageWidth / 2 + 350,stage.stageHeight - 500);
14             // 秤砣
15             var pointE:VerletPoint = makePoint(stage.stageWidth / 2 + 360,stage.stageHeight - 510);
16             var pointF:VerletPoint = makePoint(stage.stageWidth / 2 + 360,stage.stageHeight - 490);
17             var pointG:VerletPoint = makePoint(stage.stageWidth / 2 + 370,stage.stageHeight - 500);
18             // 根基
19             makeStick(pointA, pointB);
20             makeStick(pointB, pointC);
21             makeStick(pointC, pointA);
22             // 臂摆
23             makeStick(pointA, pointD);
24             // 秤砣
25             makeStick(pointD, pointE);
26             makeStick(pointD, pointF);
27             makeStick(pointE, pointF);
28             makeStick(pointE, pointG);
29             makeStick(pointF, pointG);
30             addEventListener(Event.ENTER_FRAME, onEnterFrame);
31         }
Hinge

 

 

 

 

 

 

 

posted @ 2014-01-18 20:46  actionkong  阅读(1111)  评论(0编辑  收藏  举报