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

くるくるカール with Motion Tracking

forked from mousepancyo's くるくるカール(forked from: Draw worm by mouse gesture)
Webカメラでのモーショントラッキングを追加してみました。
// forked from mousepancyo's くるくるカール(forked from: Draw worm by mouse gesture)
// forked from nutsu's Draw worm by mouse gesture.
// forked from nutsu's Worm matrix based.
/**
LOVE MATRIX.
a study for drawing curl curve.
license under the GNU Lesser General Public License.
*/

package
{
    import flash.display.Sprite;
    
    [SWF(width = "465", height = "465", frameRate = "60", backgroundColor = "0")]
    
    public class Main extends Sprite
    {
        
        private var _canvas:WormMatrix;
        
        private var _w:int = stage.stageWidth;
        private var _h:int = stage.stageHeight;
        
        public function Main()
        {
            _canvas = new WormMatrix(_w, _h);
            var sp:Sprite = new Sprite();
            sp.addChild(_canvas.video);
            sp.scaleX = -2;
            sp.scaleY = 2;
            sp.x = stage.stageWidth;
            addChild(sp);
            addChild(new Grid());
            addChild(_canvas);
        }
    }
}


// ------------ Class WormMatrix ----------------------------------//
//package {
    import frocessing.display.F5MovieClip2DBmp;
    import frocessing.geom.FMatrix2D;
    import frocessing.color.ColorHSV;
    import flash.geom.ColorTransform;
    
    import flash.media.Camera;
    import flash.media.Video;
    import flash.geom.Point;
    
    internal class WormMatrix extends F5MovieClip2DBmp{
        
        private var vms:Array;
        private var MAX_NUM:int = 150; 
        private var N:Number = 120;
        private var px:Number;
        private var py:Number;
        private var ct:ColorTransform = new ColorTransform(1, 1, 1, .99);
        private var t:Number = 0;        
        //
        public var video:Video;
        private var _cam:Camera;
        private var _tracker:Tracker;
        private var _trackX:Number = 0;
        private var _trackY:Number = 0;
        private var _p:Point = new Point();
        //
        private var _w:int;
        private var _h:int;
        
        public function WormMatrix (w:int, h:int) {
            _w = w;
            _h = h;
            //
            super( true, 0 );
            vms = [];
            initVideo();
        }
        
        public function setup():void
        {
            size( _w, _h );
            background(0, 0);
            noStroke();
            px = _tracker.trackPoint.x;
            py = _tracker.trackPoint.y;
        }
        
        private function initVideo():void {
            video = new Video(320, 240);
            _cam = Camera.getCamera();
            _cam.setMode(video.width, video.height, 10);
            video.attachCamera(_cam);
            //
            _tracker = new Tracker(_w, _h, video);            
        }
                
        public function check():void
        {
            var x0:Number = _tracker.trackPoint.x;
            var y0:Number = _tracker.trackPoint.y;
            var vx:Number = x0 - px;
            var vy:Number = y0 - py;
            var len:Number = min( mag( vx, vy ), 50 );
            
            if( len<10 ) return;
            
            var mtx:FMatrix2D = new FMatrix2D();
            mtx.rotate( atan2( vy, vx ) );
            mtx.translate( x0, y0 );
            
            createObj( mtx, len );
            
            px = x0;
            py = y0;
        }
        
        public function createObj( mtx:FMatrix2D, len:Number ):void
        {
            var angle:Number = random(PI/180, PI/2);
            if( Math.random() > 0.5 ) angle *= -1;
            var tmt:FMatrix2D = new FMatrix2D();
            tmt.scale( 0.95, 0.95 );
            tmt.rotate( angle );
            tmt.translate( len, 0 );
            var w:Number = 0.5;
               
            var obj:WormObject = new WormObject();
            obj.c1x = obj.p1x = -w * mtx.c + mtx.tx;
            obj.c1y = obj.p1y = -w * mtx.d + mtx.ty;
            obj.c2x = obj.p2x =  w * mtx.c + mtx.tx;
            obj.c2y = obj.p2y =  w * mtx.d + mtx.ty;
            obj.vmt = mtx;
            obj.tmt = tmt;
            obj.r = angle;
            obj.w = len * .1;
            obj.count = 0;
                
            vms.push( obj );
            if( vms.length > MAX_NUM )
                vms.shift();
        }
        
        public function draw():void
        {
            if( isMousePressed )
            {
                background(0, 0);
                vms = [];
            }
            
            stroke(0xFFFFFF, .5);
            
            var len:int = vms.length;
            for( var i:int=0; i<len; i++ )
            {
                var o:WormObject = vms[i];
                if( o.count<N){
                    drawWorm( o );
                    o.count++;
                }else{
                    len--;
                    vms.splice( i, 1 );
                    i--;
                }
            }
            
            check();
            
            bitmapData.colorTransform( bitmapData.rect, ct );
        }
        
        public function drawWorm( obj:WormObject ):void
        {
            
            var color:ColorHSV = new ColorHSV(t, 0.6, 1, 0.1);
            t += 0.1;
            
            if( Math.random()>0.9 ){
                obj.tmt.rotate( -obj.r*2 );
                obj.r *= -1;
            }
            obj.vmt.prepend( obj.tmt );
            var cc1x:Number = -obj.w*obj.vmt.c + obj.vmt.tx;
            var cc1y:Number = -obj.w*obj.vmt.d + obj.vmt.ty;
            var pp1x:Number = (obj.c1x+cc1x)/2;
            var pp1y:Number = (obj.c1y+cc1y)/2;
            var cc2x:Number = obj.w*obj.vmt.c + obj.vmt.tx;
            var cc2y:Number = obj.w*obj.vmt.d + obj.vmt.ty;
            var pp2x:Number = (obj.c2x+cc2x)/2;
            var pp2y:Number = (obj.c2y+cc2y)/2;
            beginFill( uint(color), .7 );
            moveTo( obj.p1x, obj.p1y );
            curveTo( obj.c1x, obj.c1y, pp1x, pp1y );
            lineTo( pp2x, pp2y );
            curveTo( obj.c2x, obj.c2y, obj.p2x, obj.p2y );
            closePath();
            endFill();
            obj.c1x = cc1x;
            obj.c1y = cc1y;
            obj.p1x = pp1x;
            obj.p1y = pp1y;
            obj.c2x = cc2x;
            obj.c2y = cc2y;
            obj.p2x = pp2x;
            obj.p2y = pp2y;
        }
    }
//}

import frocessing.geom.FMatrix2D;

internal class WormObject{
    public var c1x:Number;
    public var c1y:Number;
    public var c2x:Number;
    public var c2y:Number;
    public var p1x:Number;
    public var p1y:Number;
    public var p2x:Number;
    public var p2y:Number;
    public var w:Number;
    public var r:Number;
    public var count:int;
    public var vmt:FMatrix2D;
    public var tmt:FMatrix2D;
}



// ------------ Class Tracker ----------------------------------//
//package {
    import flash.display.BlendMode;
    import flash.filters.BlurFilter;
    import flash.display.BitmapData;
    import flash.geom.Matrix;
    import flash.geom.Point;
    import flash.geom.Rectangle;
    import flash.media.Video;
    import flash.display.Bitmap;
    import flash.display.Sprite;
    import flash.events.TimerEvent;
    import flash.utils.Timer;
    
    import org.libspark.betweenas3.*;

    internal class Tracker extends Sprite {

        private var _w:Number;
        private var _h:Number;
        private var _trackX:Number = 0;
        private var _trackY:Number = 0;
        
        // -- Track Position OutPut --//
        public var trackPoint:Point = new Point();
        
        public var _previous:BitmapData;
        public var _current:BitmapData;
        private var _px:Number;
        private var _py:Number;

        private var _blur:BlurFilter = new BlurFilter(64,64);
        private var _vid:Video;
        private var _mirror:Matrix;
        private var _point:Point = new Point();
        private var _area:Rectangle;
        private var _isMotion:Boolean = false;

        public function Tracker(w:Number, h:Number, vid:Video) {
            _w = w;
            _h = h;
            _vid = vid;
            _mirror = new Matrix();
            _mirror.scale( -1, 1);
            _mirror.translate(_vid.width, 0);
            _current = new BitmapData(_vid.width,_vid.height,false,0x000000);
            _previous = _current.clone();
            //
            var timer:Timer = new Timer(100);
            timer.addEventListener(TimerEvent.TIMER, trackerUpdate);
            timer.start();
        }
        
        private function trackerUpdate(e:TimerEvent):void{
            track();
            _trackX = _px * (_w / _vid.width);
            _trackY = _py *  (_h / _vid.height);
            //
            BetweenAS3.tween(trackPoint, { x:_trackX, y:_trackY }, null, .1).play();
        }

        private function track():void {
            _current.draw(_vid, _mirror);
            _current.draw(_previous, null, null, BlendMode.DIFFERENCE);
            _current.applyFilter(_current, _current.rect, _point, _blur);
            _current.threshold(_current, _current.rect, _point, ">",  0xFF333333, 0xFFFFFFFF);
            _previous.draw(_vid, _mirror);

            _area = _current.getColorBoundsRect(0xFFFFFFFF,0xFFFFFFFF,true);
            _isMotion = ( _area.width > ( _vid.width / 100) * 10 || _area.height > (_vid.height / 100) * 10 );

            if (_isMotion) {
                _px = _area.x;
                _py = _area.y;
            }
        }
    }
//}


// ------------ Class Grid ----------------------------------//
import flash.display.Bitmap;
import flash.display.BitmapData;

internal class Grid extends Bitmap
{
    
    public function Grid()
    {
        var bmd:BitmapData = new BitmapData(465, 465, true, 0);
        for(var i:int=0; i<720; i++){
            for(var j:int=0; j<1280; j++){
                if(i%2 == 0 && j%2 == 0){
                    bmd.setPixel32(j, i, 0xFF000000);
                }
            }
        }
        super(bmd);
    }
}