首页 > 其他 > 详细

高等物理:数值积分

时间:2014-01-19 08:28:17      阅读:525      评论:0      收藏:0      [点我收藏+]

1、欧拉积分

bubuko.com,布布扣

 

bubuko.com,布布扣
 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 }
bubuko.com,布布扣

 

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

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

bubuko.com,布布扣
 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 }
bubuko.com,布布扣

 

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。

bubuko.com,布布扣
 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 }
bubuko.com,布布扣

 

 

 

 

 

高等物理:数值积分

原文:http://www.cnblogs.com/actionkong/p/3525462.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!