In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

forked from: Circle Packing Algorithm

using linked lists and 'while' statements
Get Adobe Flash player
by nhubben 03 Jul 2011
/**
 * Copyright nhubben ( http://wonderfl.net/user/nhubben )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/3eLt
 */

///////////////////////////////////////////////////////////
//
// forked from onedayitwillmake's Circle Packing Algorithm
// using linked lists and 'while' statements
//
///////////////////////////////////////////////////////////
package {
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.geom.Point;
    import flash.geom.Vector3D;

    import frocessing.color.ColorHSV;
    import frocessing.core.F5Graphics;

    import net.hires.debug.Stats;

    [SWF(frameRate = '60', backgroundColor='0x000000',width='400', height='400' )]
    public class TestTest extends Sprite {

        protected var _nodes : Vector.<Node> = new Vector.<Node>;
        private var iterationCounter : int = 0;
        private var CENTER : Point;
        private var v : Vector3D;
        public var _view : F5Graphics;
        private var dragCircle : Node = null;

        public function TestTest() {
            this.addEventListener(Event.ADDED_TO_STAGE, initCirclePacking)
            _view = new F5Graphics(graphics);
        }

        public function initCirclePacking(e : Event) : void {
            CENTER = new Point(stage.stageWidth / 2, stage.stageHeight / 2);
            _view.clear();
            
            var maxSize : Number = 30;
            var color : ColorHSV = new ColorHSV(0, 0.8, 1.0);        
            
            var max : Number = 100;
            var n : Node;
            var size : Number;
            for(var i : int = 0; i < max; i++) {
                
                n = new Node();
                addChild(n);
             
                n.addEventListener(MouseEvent.MOUSE_DOWN, startDragging);
               
                   size = 4 + Math.random() * maxSize; 
                color.h = size / maxSize * 180 + 120;
                
                n.draw(size, color.value);
                n.setPosition(i * 8, 200 + Math.random() * 200) ;    
                
                _nodes.push(n);
                
                if( i > 0 ) {
                    _nodes[i - 1]._next = n;
                }
            }
             
              
            var stats:Stats = new Stats();
            //stats.scaleX = stats.scaleY = .25;
            addChild(stats);          


            addEventListener(Event.ENTER_FRAME, packCircles);
        }

        private function startDragging(e : MouseEvent) : void {
            dragCircle = e.target as Node;
            dragCircle._radius = dragCircle._originalRadius * 1.5;
            
            dragCircle.startDrag(false);
            stage.addEventListener(MouseEvent.MOUSE_UP, stopDragging);
        }

        private function stopDragging(e : MouseEvent) : void {
            dragCircle._radius = dragCircle._originalRadius;
            stopDrag();
            dragCircle = null;
            stage.removeEventListener(MouseEvent.MOUSE_UP, stopDragging);
        }

        
        private function packCircles(e : Event) : void {
        
            //_nodes = _nodes.sort(sortOnDistanceToCenter);
            v = new Vector3D();
            
            var n:Node = _nodes[0]; 
            var next:Node;
            
            var dx:Number, dy:Number, r:Number, d:Number;
      
            while( n ){ 
                
               if( n._next ){
                   
                    next = n._next;
                 
                   while( next ) {
                 
                    dx = next.x - n.x;
                    dy = next.y - n.y;
                    r = n._radius + next._radius;
                    d = (dx*dx) + (dy*dy);
                       
                    if (d < (r * r) - 0.01 ){
                    
                        v.x = dx;
                        v.y = dy;
                        v.normalize();
                        v.scaleBy((r - Math.sqrt(d)) * 0.5);
                            
                        if( next !== dragCircle) {
                            next.x += v.x;
                            next.y += v.y;
                        }
                            
                        if(n !== dragCircle) {
                            n.x -= v.x;
                            n.y -= v.y;
                        }
                       }
                       
                       next = ( next._next ) ? next._next : null; 
                   }
               } 
                
                n = ( n._next ) ? n._next : null;
            }

                
              
            //return;
            // push toward center
            var damping:Number = 0.01; 

            n = _nodes[0];
                
            while( n ) {
                
                if(n != dragCircle){
                    v.x = n.x - CENTER.x;
                    v.y = n.y - CENTER.y;
                    v.scaleBy(damping);
                    n.x -= v.x;
                    n.y -= v.y;
                } 
                
                n = ( n._next ) ? n._next : null; 
            }
            
        }
        
        /* 
        private function sortOnDistanceToCenter(a:Node, b:Node):int
        {
            var valueA:int = a.distanceToCenter(CENTER);
            var valueB:int = b.distanceToCenter(CENTER);
            var comparisonValue:int = 0;
            
            if(valueA > valueB) comparisonValue = -1;
            else if(valueA < valueB) comparisonValue = 1;
            
            return comparisonValue;
        } 
         * 
         */   
    }
}

import frocessing.core.F5Graphics2D;
import flash.display.Sprite;
import flash.geom.Point;

//import gs.TweenMax;
//import gs.easing.*;

class Node extends Sprite
{ 
    private var _view:F5Graphics2D;
    public var _originalRadius:Number, _radius:Number, _radiusSquared:Number;
    public var _color:uint;
    public var _next:Node;
   
    public function Node() 
    {
    }
    
    public function draw(nodeSize:Number, color:uint = 0xff0000):void
    {
        size = nodeSize;
        
        _color = color;
        
        _view = new F5Graphics2D(this.graphics);
        _view.noStroke();
        _view.beginDraw();
        _view.fillColor = color;
        _view.fillAlpha = 0.75;
        _view.circle(0,0, _radius*0.8);
        _view.circle(0,0, _radius * 0.9);
        _view.fillAlpha = 0.3;
        _view.circle(0,0, _radius);
        _view.endDraw();
    }
    
    public function setPosition(xpos:Number, ypos:Number):void
    {
        x = xpos;
        y = ypos;
    }
    
    
    /**
     * A few circle helper mathematical functions
     */
    public function containsPoint(xpos:Number, ypos:Number):Boolean
    {
        var dx:Number = x - ypos;
        var dy:Number = y - ypos;
        var distance:Number = Math.sqrt(dx*dx + dy*dy);
        
        // if it's shorter than either radi, we intersect
        return distance <= _radius;
    }
    
    public function distanceToCenter(centerPoint:Point):Number
    {
        var dx:Number = x - centerPoint.x;
        var dy:Number = y - centerPoint.y;
        var distance:Number = dx*dx + dy*dy;
        
        return distance;
    }
    
    
    public function intersects(otherNode:Node):Boolean
    {
        var dx:Number = otherNode.x - x;
        var dy:Number = otherNode.y - y;
        var distance:Number = dx*dx + dy * dy;
        
        // if it's shorter than either radi, we intersect
        return (distance < _radiusSquared || distance < otherNode._radiusSquared);
    }
    
    public function dealloc():void
    {
        _next = null;
        _view = null;
    }
    
    public function set size(value:Number):void
    {
        _radius = value;
        _originalRadius = value;

        _radiusSquared = _radius * _radius;
    }
}