守望者--AIR技术交流

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

搜索
热搜: ANE FlasCC 炼金术
查看: 1106|回复: 1

[华丽特效] 基于Voronoi的粒子特效

[复制链接]
  • TA的每日心情
    擦汗
    2018-4-10 15:18
  • 签到天数: 447 天

    [LV.9]以坛为家II

    1742

    主题

    2094

    帖子

    13万

    积分

    超级版主

    Rank: 18Rank: 18Rank: 18Rank: 18Rank: 18

    威望
    562
    贡献
    29
    金币
    52618
    钢镚
    1422

    开源英雄守望者

    发表于 2015-7-15 14:54:18 | 显示全部楼层 |阅读模式




    1. /**
    2. * Sketch of Voronoi
    3. * I will recommend seeing in "FULL SCREEN" mode.
    4. * http://alumican.net/#/c/cells
    5. *
    6. * based on 超速ボロノイ図 by fumix
    7. * @see http://wonderfl.net/c/3TKq/
    8. *
    9. * Fortune's algorithm - Wikipedia, the free encyclopedia
    10. * @see http://en.wikipedia.org/wiki/Fortune's_algorithm
    11. *
    12. * Controul > Speedy Voronoi diagrams in as3/flash
    13. * @see http://blog.controul.com/2009/05/speedy-voronoi-diagrams-in-as3flash/
    14. *
    15. * @author Yukiya Okuda<alumican.net>
    16. */
    17. package
    18. {
    19.     import com.flashdynamix.utils.SWFProfiler;
    20.     import flash.display.Graphics;
    21.     import flash.display.Shape;
    22.     import flash.display.Sprite;
    23.     import flash.display.StageAlign;
    24.     import flash.display.StageQuality;
    25.     import flash.display.StageScaleMode;
    26.     import flash.events.Event;
    27.    
    28.     public class Main extends Sprite
    29.     {
    30.         private const N:int = 700;
    31.         
    32.         private const PI:Number = Math.PI;
    33.         private const PI2:Number = PI * 2;
    34.         private const TO_DEGREE:Number = 180 / PI;
    35.         private const TO_RADIAN:Number = PI / 180;
    36.         
    37.         private var _fortune:Fortune;
    38.         private var _points:Vector.<Number2>;
    39.         private var _pointCount:int;
    40.         private var _first:Number2;
    41.         private var _oldMouseX:Number;
    42.         private var _oldMouseY:Number;
    43.         private var _background:Shape;
    44.         private var _canvas:Shape;
    45.         private var _range:Number;
    46.         
    47.         public function Main():void
    48.         {
    49.             Wonderfl.disable_capture();
    50.             addEventListener(Event.ADDED_TO_STAGE, _init);
    51.         }
    52.         
    53.         private function _init(e:Event):void
    54.         {
    55.             removeEventListener(Event.ADDED_TO_STAGE, _init);
    56.             
    57.             stage.align = StageAlign.TOP_LEFT;
    58.             stage.scaleMode = StageScaleMode.NO_SCALE;
    59.             stage.quality = StageQuality.MEDIUM;
    60.             stage.frameRate = 60;
    61.             
    62.             var sw:Number = stage.stageWidth,
    63.                 sh:Number = stage.stageHeight;
    64.             
    65.             _fortune = new Fortune();
    66.             
    67.             _background = addChild( new Shape() ) as Shape;
    68.             _background.graphics.beginFill(0x0);
    69.             _background.graphics.drawRect(0, 0, sw, sh);
    70.             _background.graphics.endFill();
    71.             
    72.             _canvas = addChild( new Shape() ) as Shape;
    73.             
    74.             _points = new Vector.<Number2>(N);
    75.             var p:Number2;
    76.             var old:Number2;
    77.             for (var i:int = 0; i < N; ++i)
    78.             {
    79.                 _points[i] = p = new Number2();
    80.                
    81.                 if (_first == null)
    82.                 {
    83.                     old = _first = p;
    84.                 }
    85.                 else
    86.                 {
    87.                     old.next = p;
    88.                     old = p;
    89.                 }
    90.             }
    91.             
    92.             _oldMouseX = mouseX;
    93.             _oldMouseY = mouseY;
    94.             
    95.             addEventListener(Event.ENTER_FRAME, _update);
    96.             stage.addEventListener(Event.RESIZE, _resize);
    97.             _resize(null);
    98.             
    99.             SWFProfiler.init(this);
    100.         }
    101.         
    102.         private function _resize(e:Event):void
    103.         {
    104.             var sw:Number = stage.stageWidth,
    105.                 sh:Number = stage.stageHeight;
    106.             
    107.             _background.width = sw;
    108.             _background.height = sh;
    109.             _range = 100 * (Math.min(sw, sh) / 465);
    110.             
    111.             var p:Number2 = _first;
    112.             do
    113.             {
    114.                 var px:Number = p.x = Math.random() * sw;
    115.                 var py:Number = p.y = Math.random() * sh;
    116.                 var angle:Number = Math.atan2(py - sh * 0.5, px - sw * 0.5);
    117.                 p.defaultVx = p.vx = 0.3 * Math.cos(angle);
    118.                 p.defaultVy = p.vy = 0.3 * Math.sin(angle);
    119.             }
    120.             while (p = p.next);
    121.         }
    122.         
    123.         private function _update(e:Event):void
    124.         {
    125.             _interaction();
    126.             _draw();
    127.         }
    128.         
    129.         private function _interaction():void
    130.         {
    131.             var sw:Number = stage.stageWidth,
    132.                 sh:Number = stage.stageHeight,
    133.                 cx:Number = sw * 0.5,
    134.                 cy:Number = sh * 0.5,
    135.                 mx:Number = mouseX,
    136.                 my:Number = mouseY,
    137.                 dx:Number,
    138.                 dy:Number,
    139.                 dist2:Number,
    140.                 px:Number,
    141.                 py:Number,
    142.                 mvx:Number = mx - _oldMouseX,
    143.                 mvy:Number = my - _oldMouseY,
    144.                 ms2:Number = Math.sqrt(mvx * mvx + mvy * mvy),
    145.                 angle:Number,
    146.                 power:Number,
    147.                 mag:Number = _range * 0.5;
    148.             
    149.             var p:Number2 = _first;
    150.             do
    151.             {
    152.                 px = p.x;
    153.                 py = p.y;
    154.                
    155.                 if (px < 0 || px > sw || py < 0 || py > sh)
    156.                 {
    157.                     angle = Math.random() * PI2;
    158.                     
    159.                     p.x  = cx + (Math.random() - 0.5) * 5;
    160.                     p.y  = cy + (Math.random() - 0.5) * 5;
    161.                     p.vx = (Math.random() - 0.5) * 1 * Math.cos(angle);
    162.                     p.vy = (Math.random() - 0.5) * 1 * Math.sin(angle);
    163.                     p.defaultVx = p.vx;
    164.                     p.defaultVy = p.vy;
    165.                 }
    166.                 else
    167.                 {
    168.                     dx = px - mx;
    169.                     dy = py - my;
    170.                     
    171.                     dist2 = dx * dx + dy * dy;
    172.                     angle = Math.atan2(dy, dx);
    173.                     
    174.                     power = mag / dist2 * ms2;
    175.                     p.vx += power * Math.cos(angle);
    176.                     p.vy += power * Math.sin(angle);
    177.                 }
    178.                
    179.                 p.defaultVx *= 1.005;
    180.                 p.defaultVy *= 1.005;
    181.                
    182.                 p.vx += (p.defaultVx - p.vx) * 0.05;
    183.                 p.vy += (p.defaultVy - p.vy) * 0.05;
    184.                
    185.                 p.x += p.vx;
    186.                 p.y += p.vy;
    187.             }
    188.             while (p = p.next);
    189.             
    190.             _fortune.points = _points;
    191.             
    192.             _oldMouseX = mx;
    193.             _oldMouseY = my;
    194.         }
    195.         
    196.         private function _draw():void
    197.         {
    198.             var segments:Vector.<Number2> = _fortune.compute(),
    199.                 g:Graphics = _canvas.graphics,
    200.                 p:Number2 = _first,
    201.                 i:int,
    202.                 n:int = segments.length,
    203.                 st:Number2,
    204.                 ed:Number2,
    205.                 dx:Number,
    206.                 dy:Number,
    207.                 dist2:Number,
    208.                 thickness:Number,
    209.                 range:Number = _range,
    210.                 mx:Number = mouseX,
    211.                 my:Number = mouseY,
    212.                 stX:Number,
    213.                 stY:Number,
    214.                 edX:Number,
    215.                 edY:Number;
    216.             
    217.             g.clear();
    218.             for (i = 0; i < n; i += 2)
    219.             {
    220.                 st = segments[i    ];
    221.                 ed = segments[i + 1];
    222.                 stX = st.x;
    223.                 stY = st.y;
    224.                 edX = ed.x;
    225.                 edY = ed.y;
    226.                
    227.                 dx = (edX + stX) * 0.5 - mx;
    228.                 dy = (edY + stY) * 0.5 - my;
    229.                 dist2 = Math.sqrt(dx * dx + dy * dy);
    230.                 thickness = (dist2 < range) ? (10 * (range - dist2) / range) : 0;
    231.                
    232.                 g.lineStyle(thickness, 0x333333);
    233.                 g.moveTo(stX, stY);
    234.                 g.lineTo(edX, edY);
    235.             }
    236.             
    237.             g.lineStyle(0, 0xffffff, 0.8);
    238.             do
    239.             {
    240.                 g.drawCircle(p.x, p.y, 1);
    241.             }
    242.             while (p = p.next);
    243.         }
    244.     }
    245. }





    246. //package  
    247. //{
    248.     /*public*/ class Number2
    249.     {
    250.         public var x:Number;
    251.         public var y:Number;
    252.         public var vx:Number;
    253.         public var vy:Number;
    254.         public var next:Number2;
    255.         public var defaultVx:Number;
    256.         public var defaultVy:Number;
    257.         
    258.         public function Number2(x:Number = 0, y:Number = 0, vx:Number = 0, vy:Number = 0):void
    259.         {
    260.             this.x = x;
    261.             this.y = y;
    262.             this.defaultVx = this.vx = vx;
    263.             this.defaultVy = this.vy = vy;
    264.         }
    265.     }
    266. //}





    267. //package
    268. //{
    269.     /*public*/ class Arc
    270.     {
    271.         public var p        : Number2;
    272.         public var next        : Arc;
    273.         public var prev        : Arc;
    274.     //    public var s0        : Seg;
    275.     //    public var s1        : Seg;
    276.         public var v0        : Number2;
    277.         public var v1        : Number2;
    278.         
    279.         //    Circle event data :
    280.         public var left        : Arc;
    281.         public var right    : Arc;
    282.         public var endX        : Number;
    283.         public var endP        : Number2;
    284.     }
    285. //}





    286. //package
    287. //{
    288.     /*
    289.      * An implementation of Steve Fortune's algorithm for computing voronoi diagrams.
    290.      * @author Matt Brubeck
    291.      *
    292.      * Modifications and optimisations:
    293.      *  ** Data structures are adapted to what's available to as3.
    294.      *  ** The beachline intersection lookup is optimised,
    295.      *     intersecting begins only near the probable intersection.
    296.      *  ** Functions are massively inlined.
    297.      *
    298.      * Todo list:
    299.      *  ** Provide for bounding box intersection,
    300.      *  ** Inline the 'intersection' method.
    301.      *  ** Design a good datastructure for the solution, which would
    302.      *     ideally contain enough neighbourhood info for region rendering,
    303.      *     extrusion and intrusion of edges and pathfinding.
    304.      *
    305.      * Original c++ code
    306.      * http://www.cs.hmc.edu/~mbrubeck/voronoi.html
    307.      */

    308.     /*public*/ class Fortune
    309.     {


    310. /////////
    311. /////////
    312. /////////    Datastructures.

    313.         //    Points are provided as a vector, which is sorted by x (increasing) before the sweep.

    314.         public var points    : Vector.<Number2>;

    315.         //    Bounding box.

    316.         private var x0        : Number;
    317. //        private var x1        : Number;
    318. //        private var y0        : Number;
    319. //        private var y1        : Number;

    320.         //    Root of the frontline and next arc to be removed.

    321.         private var root    : Arc;
    322.         private var next    : Arc;

    323.         //    Reusable objects and pools.

    324.         private var o                : Number2 = new Number2;
    325.         private static var arcPoolD : Arc;



    326. ////////
    327. ////////
    328. ////////    API.

    329.         /**
    330.          * Computes the Voronoi decomposition of the plane.
    331.          * @return A vector or vertices in pairs, describing segments ready for drawing.
    332.          */

    333.         public function compute () : Vector.<Number2>
    334.         {
    335.             //
    336.             //
    337.             //    Clear the output.

    338.             var out : Vector.<Number2> = new Vector.<Number2>,
    339.                 len    : int = 0;

    340.             //
    341.             //
    342.             //    Clear the state.

    343.             root = null;
    344.             next = null;

    345.             //
    346.             //
    347.             //    Read the pools.

    348.             var key : * ,
    349.                 arcPool : Arc = arcPoolD;

    350.             //
    351.             //
    352.             //    Vars:

    353.             var i        : int,
    354.                 j        : int,
    355.                 w        : Number,
    356.                 x        : Number,

    357.                 a        : Arc,
    358.                 b        : Arc,

    359. //                s        : Seg,
    360.                 z        : Number2,

    361.                 p        : Number2 = points [ 0 ],
    362.                 points    : Vector.<Number2> = points,
    363.                 n        : int = points.length,

    364.             //    Circle events check inlined.

    365.                 circle    : Boolean,
    366.                 eventX    : Number,

    367.                 c        : Arc,
    368.                 d        : Arc,

    369.                 aa        : Number2,
    370.                 bb        : Number2,
    371.                 cc        : Number2,

    372.                 A        : Number,
    373.                 B        : Number,
    374.                 C        : Number,
    375.                 D        : Number,
    376.                 E        : Number,
    377.                 F        : Number,
    378.                 G        : Number;


    379.             //

    380. //            y0 = p.y;
    381. //            y1 = p.y;

    382.             //
    383.             //
    384.             //    Sort points by x coord, compute the bounding box.

    385.             /////    Currently insertion sort. Quicksort?

    386.             w = points [ 0 ].x;

    387.             for ( i = 1; i < n; i ++ )
    388.             {
    389.                 p = points [ i ];

    390.                 //    Keep track of the bounding box.

    391. //                if ( p.y < y0 )
    392. //                    y0 = p.y;
    393. //                else if ( p.y > y1 )
    394. //                    y1 = p.y;

    395.                 //    Insertion sort.

    396.                 x = p.x;
    397.                 if ( x < w )
    398.                 {
    399.                     j = i;
    400.                     while ( ( j > 0 ) && ( points [ int ( j - 1 ) ].x > x ) )
    401.                     {
    402.                         points [ j ] = points [ int ( j - 1 ) ];
    403.                         j--;
    404.                     }
    405.                     points [ j ] = p;
    406.                 }
    407.                 else
    408.                     w = x;
    409.             }

    410.             //    Get x bounds.

    411.             x0 = points [ 0 ].x;
    412. //            x1 = points [ n - 1 ].x;

    413.             //    Add margins to the bounding box.
    414. /*
    415.             var dx : Number = (x1 - x0 + 1) / 5.0,
    416.                 dy : Number = dy = (y1 - y0 + 1) / 5.0;
    417.             x0 -= dx;
    418.             x1 += dx;
    419.             y0 -= dy;
    420.             y1 += dy;

    421. //            trace ( x0, x1, y0, y1 );
    422. //*/
    423.             //
    424.             //
    425.             //    Process.

    426.             i = 0;
    427.             p = points [ 0 ];
    428.             x = p.x;

    429.             for ( ;; )
    430.             {

    431.                 //
    432.                 //    Check circle events. /////////////////////////

    433.                 if ( a )
    434.                 {
    435.                     //    Check for arc a.

    436.                     circle = false;

    437.                     if ( a.prev && a.next )
    438.                     {
    439.                         aa = a.prev.p,
    440.                         bb = a.p,
    441.                         cc = a.next.p;

    442.                         //    Algorithm from O'Rourke 2ed p. 189.

    443.                         A = bb.x - aa.x,
    444.                         B = bb.y - aa.y,
    445.                         C = cc.x - aa.x,
    446.                         D = cc.y - aa.y;

    447.                         //    Check that bc is a "right turn" from ab.

    448.                         if ( A * D - C * B <= 0 )
    449.                         {
    450.                             E = A * ( aa.x + bb.x ) + B * ( aa.y + bb.y ),
    451.                             F = C * ( aa.x + cc.x ) + D * ( aa.y + cc.y ),
    452.                             G = 2 * ( A * ( cc.y - bb.y ) - B * ( cc.x - bb.x ) );

    453.                             //    Check for colinearity.

    454. //                            if ( G > 0.000000001 || G < -0.000000001 )
    455.                             if ( G )
    456.                             {
    457.                                 //    Point o is the center of the circle.

    458.                                 o.x = ( D * E - B * F ) / G;
    459.                                 o.y = ( A * F - C * E ) / G;

    460.                                 //    o.x plus radius equals max x coordinate.

    461.                                 A = aa.x - o.x;
    462.                                 B = aa.y - o.y;
    463.                                 eventX = o.x + Math.sqrt ( A * A + B * B );

    464.                                 if ( eventX >= w )
    465.                                     circle = true;
    466.                             }
    467.                         }
    468.                     }

    469.                     //    Remove from queue.

    470.                     if ( a.right )
    471.                         a.right.left = a.left;
    472.                     if ( a.left )
    473.                         a.left.right = a.right;
    474.                     if ( a == next )
    475.                         next = a.right;

    476.                     //    Record event.

    477.                     if ( circle )
    478.                     {
    479.                         a.endX = eventX;
    480.                         if ( a.endP )
    481.                         {
    482.                             a.endP.x = o.x;
    483.                             a.endP.y = o.y;
    484.                         }
    485.                         else
    486.                         {
    487.                             a.endP = o;
    488.                             o = new Number2;
    489.                         }

    490.                         d = next;
    491.                         if ( !d )
    492.                         {
    493.                             next = a;
    494.                         }
    495.                         else for ( ;; )
    496.                         {
    497.                             if ( d.endX >= eventX )
    498.                             {
    499.                                 a.left = d.left;
    500.                                 if ( d.left )
    501.                                     d.left.right = a;
    502.                                 if ( next == d )
    503.                                     next = a;
    504.                                 a.right = d;
    505.                                 d.left = a;

    506.                                 break;
    507.                             }
    508.                             if ( !d.right )
    509.                             {
    510.                                 d.right = a;
    511.                                 a.left = d;
    512.                                 a.right = null;

    513.                                 break;
    514.                             }
    515.                             d = d.right;
    516.                         }
    517.                     }
    518.                     else
    519.                     {
    520.                         a.endX = NaN;
    521.                         a.endP = null;
    522.                         a.left = null;
    523.                         a.right = null;
    524.                     }

    525.                     //    Push next arc to check.

    526.                     if ( b )
    527.                     {
    528.                         a = b;
    529.                         b = null;
    530.                         continue;
    531.                     }
    532.                     if ( c )
    533.                     {
    534.                         a = c;
    535.                         c = null;
    536.                         continue;
    537.                     }
    538.                     a = null;
    539.                 }

    540.                 //////////////////////////////////////////////////
    541.                 //

    542.                 if ( next && next.endX <= x )
    543.                 {
    544.                     //
    545.                     //    Handle next circle event.

    546.                     //    Get the next event from the queue. ///////////

    547.                     a = next;
    548.                     next = a.right;
    549.                     if ( next )
    550.                         next.left = null;
    551.                     a.right = null;

    552.         //DEBUG*/    Debug.frontRemove ( a, root );

    553.                     //    Start a new edge.

    554. //                    s = new Seg;
    555. //                    s.start = a.endP;

    556.                     //    Remove the associated arc from the front.

    557.                     if ( a.prev )
    558.                     {
    559.                         a.prev.next = a.next;
    560. //                        a.prev.s1 = s;
    561.                         a.prev.v1 = a.endP;
    562.                     }
    563.                     if ( a.next )
    564.                     {
    565.                         a.next.prev = a.prev;
    566. //                        a.next.s0 = s;
    567.                         a.next.v0 = a.endP;
    568.                     }

    569.                     //    Finish the edges before and after a.
    570. /*
    571.                     if ( a.s0 && !a.s0.done )
    572.                     {
    573.                         a.s0.done = true;
    574. //                        a.s0.end = a.endP;
    575.                         out [ len ++ ] = a.s0.start;
    576.                         out [ len ++ ] = a.endP;
    577.                     }
    578.                     if ( a.s1 && !a.s1.done )
    579.                     {
    580.                         a.s1.done = true;
    581. //                        a.s1.end = a.endP;
    582.                         out [ len ++ ] = a.s1.start;
    583.                         out [ len ++ ] = a.endP;
    584.                     }
    585. */
    586.                     if ( a.v0 )
    587.                     {
    588.                         out [ len ++ ] = a.v0;
    589.                         a.v0 = null;
    590.                         out [ len ++ ] = a.endP;
    591.                     }
    592.                     if ( a.v1 )
    593.                     {
    594.                         out [ len ++ ] = a.v1;
    595.                         a.v1 = null;
    596.                         out [ len ++ ] = a.endP;
    597.                     }

    598.                     //    Keep a ref for collection.

    599.                     d = a;

    600.                     //    Recheck circle events on either side of p:

    601.                     w = a.endX;
    602.                     if ( a.prev )
    603.                     {
    604.                         b = a.prev;
    605.                         a = a.next;
    606.                     }
    607.                     else
    608.                     {
    609.                         a = a.next;
    610.                         b = null;
    611.                     }
    612.                     c = null;

    613.                     //    Collect.

    614.                     d.v0 = null;
    615.                     d.v1 = null;
    616.                     d.p = null;
    617.                     d.prev = null;
    618.                     d.endX = NaN;
    619.                     d.endP = null;
    620.                     d.next = arcPool;
    621.                     arcPool = d;

    622.                     //////////////////////////////////////////////////
    623.                     //
    624.                 }
    625.                 else
    626.                 {
    627.                     if ( !p )
    628.                         break;

    629.                     //
    630.                     //    Handle next site event. //////////////////////

    631.                     if ( !root ) {
    632. //                        root = new Arc;
    633.                         if ( arcPool )
    634.                         {
    635.                             root = arcPool;
    636.                             arcPool = arcPool.next;
    637.                             root.next = null;
    638.                         }
    639.                         else
    640.                             root = new Arc;
    641.                         root.p = p;
    642.         //DEBUG*/        Debug.frontInsert ( root, root );
    643.                     }
    644.                     else
    645.                     {

    646.                         z = new Number2;

    647.                         //    Find the first arc with a point below p,
    648.                         //    and start searching for the intersection around it.

    649.                         a = root.next;
    650.                         if ( a )
    651.                         {
    652.                             while ( a.next )
    653.                             {
    654.                                 a = a.next;
    655.                                 if ( a.p.y >= p.y )
    656.                                     break;
    657.                             }

    658.                             //    Find the intersecting curve.

    659.                             intersection ( a.prev.p, a.p, p.x, z );
    660.                             if ( z.y <= p.y )
    661.                             {
    662.                                 //    Search for the intersection to the south of i.

    663.                                 while ( a.next )
    664.                                 {
    665.                                     a = a.next;
    666.                                     intersection ( a.prev.p, a.p, p.x, z );
    667.                                     if ( z.y >= p.y )
    668.                                     {
    669.                                         a = a.prev;
    670.                                         break;
    671.                                     }
    672.                                 }
    673.                             }
    674.                             else
    675.                             {
    676.                                 //    Search for the intersection above i.

    677.                                 a = a.prev;
    678.                                 while ( a.prev )
    679.                                 {
    680.                                     a = a.prev;
    681.                                     intersection ( a.p, a.next.p, p.x, z );
    682.                                     if ( z.y <= p.y )
    683.                                     {
    684.                                         a = a.next;
    685.                                         break;
    686.                                     }
    687.                                 }
    688.                             }
    689.                         }
    690.                         else
    691.                             a = root;

    692.                         //    New parabola will intersect arc a. Duplicate a.

    693.                         if ( a.next )
    694.                         {
    695. //                            b = new Arc;
    696.                             if ( arcPool )
    697.                             {
    698.                                 b = arcPool;
    699.                                 arcPool = arcPool.next;
    700.                                 b.next = null;
    701.                             }
    702.                             else
    703.                                 b = new Arc;
    704.                             b.p = a.p;
    705.                             b.prev = a;
    706.                             b.next = a.next;
    707.                             a.next.prev = b;
    708.                             a.next = b;
    709.                         }
    710.                         else
    711.                         {
    712. //                            b = new Arc;
    713.                             if ( arcPool )
    714.                             {
    715.                                 b = arcPool;
    716.                                 arcPool = arcPool.next;
    717.                                 b.next = null;
    718.                             }
    719.                             else
    720.                                 b = new Arc;
    721.                             b.p = a.p;
    722.                             b.prev = a;
    723.                             a.next = b;
    724.                         }
    725. //                        a.next.s1 = a.s1;
    726.                         a.next.v1 = a.v1;

    727.                         //    Find the point of intersection.

    728.                         z.y = p.y;
    729.                         z.x = ( a.p.x * a.p.x + ( a.p.y - p.y ) * ( a.p.y - p.y ) - p.x * p.x )
    730.                                 / ( 2 * a.p.x - 2 * p.x );

    731.                         //    Add p between i and i->next.

    732. //                        b = new Arc;
    733.                         if ( arcPool )
    734.                         {
    735.                             b = arcPool;
    736.                             arcPool = arcPool.next;
    737.                             b.next = null;
    738.                         }
    739.                         else
    740.                             b = new Arc;

    741.                         b.p = p;
    742.                         b.prev = a;
    743.                         b.next = a.next;

    744.                         a.next.prev = b;
    745.                         a.next = b;

    746.                         a = a.next;    //    Now a points to the new arc.

    747.                         //    Add new half-edges connected to i's endpoints.
    748. /*
    749.                         s = new Seg;
    750.                         s.start = z;
    751.                         a.prev.s1 = a.s0 = s;
    752.                         s = new Seg;
    753.                         s.start = z;
    754.                         a.next.s0 = a.s1 = s;
    755. */
    756.                         a.prev.v1 = z;
    757.                         a.next.v0 = z;
    758.                         a.v0 = z;
    759.                         a.v1 = z;

    760.                         //    Check for new circle events around the new arc:

    761.                         b = a.next;
    762.                         a = a.prev;
    763.                         c = null;
    764.                         w = p.x;

    765.             //DEBUG*/    Debug.frontInsert ( a, root );
    766.                     }

    767.                     //////////////////////////////////////////////////
    768.                     //

    769.                     i ++;
    770.                     if ( i >= n )
    771.                     {
    772.                         p = null;
    773.                         x = Number.MAX_VALUE;
    774.                     }
    775.                     else
    776.                     {
    777.                         p = points [ i ];
    778.                         x = p.x;
    779.                     }
    780.                 }
    781.             }
    782. //*/

    783. /*
    784.             //    Clean up dangling edges.

    785.             //    Advance the sweep line so no parabolas can cross the bounding box.
    786.             x = x1;
    787.             x = x1 + ( x1 - x0 ) + ( y1 - y0 );
    788.             x *= 2;

    789.             //    Extend each remaining segment to the new parabola intersections.
    790.             var arc : Arc = root;
    791.             for ( ;; )
    792.             {
    793.                 if ( arc.s1 )
    794.                     arc.s1.finish ( intersection ( arc.p, arc.next.p, x, new Number2 ) );
    795.                 arc = arc.next;
    796.                 if ( !arc.next )
    797.                     break;
    798.             }
    799. //*/
    800.             //
    801.             //
    802.             //    Store the pools.

    803.             arcPoolD = arcPool;

    804.             //
    805.             //
    806.             //    Return the result ready for drawing.

    807.             return out;
    808.         }



    809.         /**
    810.          * Where do two parabolas intersect?
    811.          * @param    p0 A Number2 object describing the site for the first parabola.
    812.          * @param    p1 A Number2 object describing the site for the second parabola.
    813.          * @param    l The location of the sweep line.
    814.          * @param    res A Number2 object in which to store the intersection.
    815.          * @return The point of intersection.
    816.          */
    817.         public function intersection ( p0 : Number2, p1 : Number2, l : Number, res : Number2 ) : Number2
    818.         {
    819.             var p    : Number2 = p0,
    820.                 ll    : Number = l * l;

    821.             if ( p0.x == p1.x )
    822.                 res.y = ( p0.y + p1.y ) / 2;
    823.             else if ( p1.x == l )
    824.                 res.y = p1.y;
    825.             else if ( p0.x == l )
    826.             {
    827.                 res.y = p0.y;
    828.                 p = p1;
    829.             }
    830.             else
    831.             {
    832.                 //    Use the quadratic formula.

    833.                 var z0 : Number = 0.5 / ( p0.x - l ); // 1 / ( 2*(p0.x - l) )
    834.                 var z1 : Number = 0.5 / ( p1.x - l ); // 1 / ( 2*(p1.x - l) )

    835.                 var a : Number = z0 - z1;
    836.                 var b : Number = -2 * ( p0.y * z0 - p1.y * z1 );
    837.                 var c : Number = ( p0.y * p0.y + p0.x * p0.x - ll ) * z0
    838.                                - ( p1.y * p1.y + p1.x * p1.x - ll ) * z1;

    839.                 res.y = ( - b - Math.sqrt ( b * b - 4 * a * c ) ) / ( 2 * a );
    840.             }
    841.             
    842.             //    Plug back into one of the parabola equations.

    843.             res.x = ( p.x * p.x + ( p.y - res.y ) * ( p.y - res.y ) - ll )
    844.                     / ( 2 * p.x - 2 * l );
    845.             return res;
    846.         }

    847.     }
    848. //}
    复制代码






    本文来自:http://wonderfl.net/c/iNy0

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有帐号?立即注册

    x
    守望者AIR技术交流社区(www.airmyth.com)
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2019-2-24 01:34
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    0

    主题

    38

    帖子

    868

    积分

    上士

    Rank: 5Rank: 5

    威望
    20
    贡献
    0
    金币
    14
    钢镚
    0
    发表于 2019-2-24 02:26:36 | 显示全部楼层
    感谢分享!~
    守望者AIR技术交流社区(www.airmyth.com)
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    
    关闭

    站长推荐上一条 /4 下一条

    QQ|手机版|Archiver|网站地图|小黑屋|守望者 ( 京ICP备14061876号

    GMT+8, 2024-3-28 16:25 , Processed in 0.049118 second(s), 31 queries .

    守望者AIR

    守望者AIR技术交流社区

    本站成立于 2014年12月31日

    快速回复 返回顶部 返回列表