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

Box2DObject生成 + MouseGesture

now only support: rectangle, circle, triangle
* inspired by Mouse Gesture Recognition from bytearray.org
* 2010-01-26 19:18:00
Get Adobe Flash player
by civet 08 Jan 2016
/**
 * Copyright civet ( http://wonderfl.net/user/civet )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/5IQf
 */

/**
 * now only support: rectangle, circle, triangle
 * inspired by Mouse Gesture Recognition from bytearray.org
 * 2010-01-26 19:18:00
 */
package
{
    import com.actionsnippet.qbox.QuickBox2D;
    import flash.display.*;
    import flash.events.*;
    import flash.geom.Point;
    import flash.utils.getTimer;
    
    
    public class Main extends MovieClip
    {
        private var sim:QuickBox2D;
        private var time:int;
        private var source:BitmapData;
        private var shape:Shape;
        private var wayPoints:Array = [];
        
        
        public function Main()
        {
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;
            stage.frameRate = 60;
            init();
        }

        private function init():void
        {
            sim = new QuickBox2D(this, {debug:true});
            sim.createStageWalls();
            sim.start();
            sim.mouseDrag();
            
            source = new BitmapData(stage.stageWidth, stage.stageHeight, false, 0xffffff);
            shape = new Shape();
            var canvas:Bitmap = new Bitmap(source);
            canvas.alpha = 0.5;
            this.addChild(canvas);
            
            stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
            stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
        }
        
        private function onMouseDown(e:MouseEvent):void
        {
            time = getTimer();
            wayPoints.length = 0;
            
            this.addEventListener(Event.ENTER_FRAME, onTracing);
        }
        
        private function onMouseUp(e:MouseEvent):void
        {
            this.removeEventListener(Event.ENTER_FRAME, onTracing);
            source.fillRect(source.rect, 0xffffff);
            
            if(wayPoints.length < 1) return;
            var p:Array = simplify(wayPoints);
            var v:Array = toVectors( p );
            var s:String = serialize(v).toString().replace(/,/g, '');
            
            var i:int = recognize(s);
            createShape(i);
        }
                
        private function onTracing(e:Event):void
        {
            if((getTimer() - time) < 30) return;
            time = getTimer();
            
            wayPoints[wayPoints.length] = new Point(mouseX, mouseY);
            
            drawWay(wayPoints);
        }
        
        private function drawWay(pts:Array):void
        {
            var g:Graphics = shape.graphics;
            g.clear();
            
            var len:int = pts.length;
            for(var i:int=0; i < len; ++i) {
                g.beginFill(0xff0000);
                g.drawCircle(pts[i].x, pts[i].y, 3);
                g.endFill();
            }
            
            source.fillRect(source.rect, 0xffffff);
            source.draw(shape);
        }
                
        private var maxPoint:Number = 17;
        private function simplify(points:Array):Array
        {
            var p:Array = points.slice();
            if(p.length <= maxPoint) return p;
            while(p.length > maxPoint) {
                var dMin:Number = Number.POSITIVE_INFINITY;
                var d:Number;
                var iMarker:int;
                for(var i:int=2; i<p.length-1; i++) {
                    d = Point.distance(p[i], p[i-1]);
                    if(d<dMin) {
                        dMin = d;
                        iMarker = i;
                    }
                }
                p[iMarker] = new Point((p[iMarker].x+p[iMarker-1].x)/2, (p[iMarker].y+p[iMarker-1].y)/2);
                p.splice(iMarker-1,    1);    
            }
            return p;
        }
        
        private function toVectors(points:Array):Array
        {
            var v:Array = new Array();
            for(var i:int=1; i<points.length; i++) {
                var vector:Point = new Point((points[i].x-points[i-1].x), (points[i].y-points[i-1].y));
                vector.normalize(1);
                vector.x = int( Math.round(vector.x) );
                vector.y = int( Math.round(vector.y) );
                v[i-1] = vector;
            }
            return v;
        }
        
        private var pattern:Array = [[7, 8, 9], [4, 5, 6], [1, 2, 3]];
        private function serialize(points:Array):Array {
            var s:Array = new Array();
            for(var i:int=0; i < points.length; i++) {
                var pt:Point = points[i];
                s.push( pattern[1 + pt.y][1 + pt.x] );
            }
            return s;
        }
        
        private var gesture:Array = ["5555555555555555",                                
        "6666666666666666",
        "2222222222222222",
        "4444444444444444",
        "8888888888888888",
        "3333333333333333",
        "1111111111111111",
        "7777777777777777",
        "9999999999999999",
        "6666222244448888",
        "4444222266668888",
        "4441223669887444",
        "6663221447889666",
        "1111166666677777",
        "3333366666699999"
        ];
        private function recognize(s:String):int
        {
            var dMin:Number = Number.POSITIVE_INFINITY;
            var d:Number;
            var iMarker:int;
            for(var i:int=0; i < gesture.length; ++i) {
                d = Distance.levenshtein(s, gesture[i]);
                if(d < dMin) {
                    dMin = d;
                    iMarker = i;
                }
            }
            trace("input: " + s);
            trace("match : " + gesture[iMarker]);
            trace("distance: " + dMin);
            return iMarker;
        }
        
        
        private function createShape(type:int):void
        {
            switch(type) {
                case 9:
                case 10:
                    sim.addBox({x:10, y:2, width:2, height:2});
                    break;
                case 11:
                case 12:
                    sim.addCircle({x:10, y:2, radius:1});
                    break;
                case 13:
                case 14:
                    sim.addPoly({x:10, y:2, verts:[[0,0,2,2,0,2]]});
                    break;
            }
        }
        
    }
}


class Distance {
    /* Compute Levenshtein distance */
    public static function levenshtein(s:String, t:String):uint {
        var cost:uint;
        // Step 1
        var n:uint = s.length;
        var m:uint = t.length;
        if(n==0) return m;
        if(m==0) return n;
        // Step 2
        var d:Array = getArray2D(n+1, m+1, 0);
        for(var i:uint=0; i<=n; i++) { d[i][0] = i; }
        for(var j:uint=0; j<=m; j++) { d[0][j] = j; }
        // Step 3
        for(i=1; i<=n; i++) {
            var sChar:String = s.charAt(i-1);
            // Step 4
            for(j=1; j<=m; j++) {
                var tChar:String = t.charAt(j-1);
                // Step 5
                if(sChar==tChar) cost = 0;
                else cost = 1;
                // Step 6
                d[i][j] = Math.min(d[i-1][j]+1, d[i][j-1]+1, d[i-1][j-1]+cost);
            }
        }
        // Step 7
        return d[n][m];
    }
    /* get Filled 2D Table(Matrix) */
    private static function getArray2D(n:uint, m:uint, element:*):Array {
        var matrix:Array = new Array(n);
        for (var i:uint=0; i<n; i++) {
            matrix[i] = new Array(m);
            for (var j:uint=0; j<m; j++) {
                matrix[i][j] = element;
            }
        }
        return matrix;
    }
}