zoukankan      html  css  js  c++  java
  • 高等物理:数值积分

    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

     

     

     

     

  • 相关阅读:
    Ubuntu 11.10版本下的软件中心安装软件的默认路径
    C++中构造函数调用与申明方式的关系
    VMware Workstation 虚拟机(客户机)创建和主机共享文件夹
    观察者模式——三英雄战吕布
    如何在yarn上运行Hello World(二)
    Cat 客户端如何构建调用链消息树
    Cat 跨线程之 TaggedTransaction 用法和原理分析
    Cat 客户端采用什么策略上报消息树
    Cat 跨线程之 ForkedTransaction 用法和原理分析
    jest for elasticsearch
  • 原文地址:https://www.cnblogs.com/actionkong/p/3525462.html
Copyright © 2011-2022 走看看