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

binary tree HV-Drawing

not so tight
but when I try to do so
overlapping occurs :(
/**
 * Copyright wrotenodoc ( http://wonderfl.net/user/wrotenodoc )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/ytnH
 */

// forked from wrotenodoc's binary tree drawing
package {

    import flash.display.Sprite;
    import flash.display.Graphics
    
    import flash.text.TextField
    
    public class FlashTest extends Sprite {
        
        private var canv:Sprite
        private var tree:Tree
        
        private const size:Number = 8
        private const spaceX:Number = 30
        private const spaceY:Number = 20
        
        private var _tf:TextField = new TextField
        
        public function FlashTest() {
            // write as3 code here..
            canv = new Sprite
            tree = new Tree
            
            addChild(canv)
            canv.x = stage.stageWidth * 0.25
            canv.y = stage.stageHeight * 0.1
            
            addChild(_tf)
            _tf.autoSize = "left"
            
            build(tree, 0)
            process(tree)
            adjustRoot(tree)
            render(canv.graphics, tree)
            
            stage.addEventListener("mouseMove", function(e:Object):void {
                canv.scaleY = 0.1 + 0.9 * (mouseY / stage.stageHeight)
            })
        }
        
        private function build(T:Tree, level:int):void {
            var prob:Number = 1 / (1 + level*0.1)
            if(Math.random() < prob){
                T.left = new Tree
                T.left.parent = T
                T.left.level = T.level + 1
                build(T.left, level+1)
            }
            if(Math.random() < prob){
                T.right = new Tree
                T.right.parent = T
                T.right.level = T.level + 1
                build(T.right, level+4)
            }
        }
        
        public function render(g:Graphics, T:Tree):void {
            var level:int = 0
            var queue:Array = [T]
            var num:int
            while(queue.length){
                num = queue.length
                while(num--){
                    T = queue.shift()
                    if(T.level == 0) g.lineStyle(2, 0x0)
                    g.beginFill(0x123456, 1)
                    g.drawCircle(T.x * spaceX, T.y * spaceY, size)
                    g.endFill()
                    g.lineStyle()
                    if(T.parent){
                        g.lineStyle(1, T.parent.left==T ? 0xff0000 : 0x0000ff)
                        g.moveTo(T.x * spaceX, T.y * spaceY)
                        g.lineTo(T.parent.x * spaceX, T.parent.y*spaceY)
                        g.lineStyle()
                    }
                    if(T.left) queue.push(T.left)
                    if(T.right) queue.push(T.right)
                }
                level++
            }
        }
    
        public function process(T:Tree):void {
            if(T == null) return
            process(T.right)
            process(T.left)
            
            if(T.left == null && T.right == null){
                T.x = T.y = 0
            }else if(T.left == null){
                T.y = T.right.y
                T.x = T.right.x - 1
            }else if(T.right == null){
                T.x = T.left.x
                T.y = T.left.y - 1
            }else{
                T.y = T.right.y
                T.x = T.right.x - 1
                var dy:int = T.y - T.left.y + (T.right.leftmost - T.right.y) + 1
                var dx:int = T.x - T.left.x
                fmap(function(t:Tree):void { t.x += dx ; t.y += dy }, T.left)
            }
        }
        
        public function adjustRoot(T:Tree):void {
            var x0:int = T.x, y0:int = T.y
            fmap(function(t:Tree):void { t.x -= x0 ; t.y -= y0 }, T)
        }
    
        public function fmap(f:Function, t:Tree):void {
            if(t){
                f(t)
                if(t.left) fmap(f, t.left)
                if(t.right) fmap(f, t.right)
            }
        }
        
    }
    
}

class Tree {
    
    public var left:Tree
    public var right:Tree
    public var parent:Tree
    
    public var x:int
    public var y:int
    public var level:int = 0
    
    public function Tree() {
        //
    }
    
    public function get leftmost():int {
        var t:Tree = this
        var most:int = int.MIN_VALUE
        traverse(t)
        return most
        function traverse(t:Tree):void {
            if(t.y > most) most = t.y
            if(t.left) traverse(t.left)
            if(t.right) traverse(t.right)
        }
    }
    public function get rightmost():Tree {
        var t:Tree = this, s:Tree
        while(t.right) t = t.right
        if(t.left){
            s = t.left.rightmost
            if(s.x > t.x) t = s
        }
        return t
    }
    
}