守望者--AIR技术交流

标题: 基于Voronoi的粒子特效 [打印本页]

作者: 破晓    时间: 2015-7-15 14:54
标题: 基于Voronoi的粒子特效


http://swf.wonderfl.net/swf/usercode/8/83/83c0/83c0fa8eb9e85ce32eccd202190d426f98a22cde.swf?t=1436942960055

  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. //}
复制代码




[attach]1225[/attach]

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

作者: lxz    时间: 2019-2-24 02:26
感谢分享!~




欢迎光临 守望者--AIR技术交流 (http://www.airmyth.com/)