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

ドロネー三角分割でWEBカメラ表示

下記のフォークです。
http://wonderfl.net/c/4cr7/read

モノトーンにして、境界線出して、その境界線上に濃くなるように、ドロネー三角分割して色を塗った
/**
 * Copyright s26 ( http://wonderfl.net/user/s26 )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/wlLw
 */

package {
    import flash.text.TextField;
    import flash.geom.*;
    import flash.events.*;
    import flash.display.*;
    import flash.media.*;
    import flash.utils.*;
    public class FlashTest extends Sprite {
        
        private var _bmp:Bitmap;
        private var _bmd:BitmapData;
        private var _bmdRect:Rectangle;

        
        private var camera:Camera;
        private var video:Video;
        
        public function FlashTest() {
            delaunay = new Delaunay();
            points = new Vector.<Point>();
            camera = Camera.getCamera();
            if (camera != null) {
                video = new Video(465,465);
                video.attachCamera(camera);
                //addChild(video);
                _bmd = new BitmapData(video.width, video.height)
                init();
            }
            
        }
        private function init():void{
            this.stage.align = StageAlign.TOP_LEFT;
            this.stage.scaleMode = StageScaleMode.NO_SCALE;
            this.stage.quality = "low";
            this.stage.frameRate =1;
            _bmp = new Bitmap(_bmd);
            //addChild(_bmp);
            //stage.addEventListener(MouseEvent.MOUSE_UP,onEnterFrameHandler);
            stage.addEventListener(Event.ENTER_FRAME,onEnterFrameHandler);
        }
        
        private var tf:TextField = new TextField();
        private var delaunay:Delaunay;
        private var indices:Vector.<int>;
        private var points:Vector.<Point>;
        public static var colorArray:Array;
        private function onEnterFrameHandler(e:Event):void{
            
            _bmd.draw(video);
            var _glayArray:Array = new Array();
            colorArray = new Array();
            for(var i:uint = 0 ; i < 465 ; i++){
                var _glayArrayInner:Array = new Array();
                _glayArray.push(_glayArrayInner);
                var _colorArrayInner:Array = new Array();
                colorArray.push(_colorArrayInner);
                
                for(var j:uint = 0 ; j < 465 ; j++){
                    var color  : uint = _bmd.getPixel(i,j);
                    var _red   : uint = (color >> 16) & 0xFF;
                    var _green : uint = (color >>  8) & 0xFF;
                    var _blue  : uint = (color >>  0) & 0xFF;
                    var _grey:uint = (_red + _green + _blue)/3;
                    _grey = 0.299 *_red + 0.587 *_green + 0.114 *_blue;
                    //_glayArray[i][j] = _grey;
                    if(Math.abs(_grey)<20){
                        //_bmd.setPixel(i,j,0x000000);
                        _glayArray[i][j] = 0x000000;
                    }else if(Math.abs(_grey)<40){
                        //_bmd.setPixel(i,j,0x333333);
                        _glayArray[i][j] = 0x333333;
                    }else if(Math.abs(_grey)<80){
                        //_bmd.setPixel(i,j,0x666666);
                        _glayArray[i][j] = 0x666666;
                    }else if(Math.abs(_grey)<120){
                        //_bmd.setPixel(i,j,0x999999);
                        _glayArray[i][j] = 0x999999;
                    }else if(Math.abs(_grey)<160){
                        //_bmd.setPixel(i,j,0xcccccc);
                        _glayArray[i][j] = 0xcccccc;
                    }else{
                        //_bmd.setPixel(i,j,0xffffff);
                        _glayArray[i][j] = 0xffffff;
                    }
                    colorArray[i][j] = color;
                }
            }
            points.length = 0;
            for(i =1 ; i < 464 ; i++){
                for(j = 1 ; j < 464 ; j++){
                    var hensa:int = 0;
                    for(var n:int = -1 ; n < 2 ; n++){
                        for(var m:int = -1 ; m < 2 ; m++){
                            hensa -= _glayArray[i+n][j+m];
                        }
                    }
                    hensa += _glayArray[i][j]*9;
                    _bmd.setPixel(i,j,0xffffff);
                    if(hensa > 10){
                        if(Math.random()*20 < 1){
                            //_bmd.setPixel(i,j,0x000000);
                            points.push(new Point(i,j));
                        }

                    }else if(hensa < -10){
                        if(Math.random()*20 < 1){
                            //_bmd.setPixel(i,j,0x000000);
                            points.push(new Point(i,j));
                        }
                    }else{
                        //_bmd.setPixel(i,j,0xffffff);
                    }


                }
            }
            graphics.clear();
            
            graphics.beginFill( 0xCC0000 );
            for (i = 0; i < points.length; i++){
                //graphics.drawCircle( points[i].x, points[i].y, 2 );
            }
            graphics.endFill();
            
            
            indices = delaunay.compute( points );
            
            
            //graphics.lineStyle( 0, 0x666666 );
            delaunay.render( graphics, points, indices );
            
        }
       
    }
}

import flash.display.Graphics;
import flash.geom.Point;
class Delaunay    
{
    static public var EPSILON:Number = Number.MIN_VALUE;
    static public var SUPER_TRIANGLE_RADIUS:Number = 10000000;
    private var indices:Vector.<int>;
    private var circles:Vector.<Number>;
    public function compute( points:Vector.<Point> ):Vector.<int>
    {
        var nv:int = points.length;
        if (nv < 3) return null;
        var d:Number = SUPER_TRIANGLE_RADIUS;
        points.push(     new Point( 0, -d ), new Point( d, d ), new Point( -d, d )    );
        indices = Vector.<int>( [ points.length-3, points.length-2, points.length-1 ] );
        circles = Vector.<Number>( [ 0, 0, d ] );
        var edgeIds:Vector.<int> = new Vector.<int>();
        var i:int, j:int, k:int, id0:int, id1:int, id2:int;
        for ( i = 0; i < nv; i++)
        {
            for ( j = 0; j < indices.length; j+=3 )
            {
                if (     circles[ j + 2 ] > EPSILON         &&         circleContains( j, points[ i ] )    )
                {
                    id0 = indices[ j ];
                    id1 = indices[ j + 1 ];
                    id2 = indices[ j + 2 ];
                    edgeIds.push( id0, id1, id1, id2, id2, id0 );
                    indices.splice( j, 3 );
                    circles.splice( j, 3 );
                    j -= 3;
                }
            }
            for ( j = 0; j < edgeIds.length; j+=2 )
            {
                for ( k = j + 2; k < edgeIds.length; k+=2 )
                {
                    if(    (    edgeIds[ j ] == edgeIds[ k ] && edgeIds[ j + 1 ] == edgeIds[ k + 1 ]    )
                    ||    (    edgeIds[ j + 1 ] == edgeIds[ k ] && edgeIds[ j ] == edgeIds[ k + 1 ]    )    )
                    {
                        edgeIds.splice( k, 2 );
                        edgeIds.splice( j, 2 );
                        j -= 2;
                        k -= 2;
                        if ( j < 0 ) break;
                        if ( k < 0 ) break;
                    }
                }
            }
            for ( j = 0; j < edgeIds.length; j+=2 )
            {
                indices.push( edgeIds[ j ], edgeIds[ j + 1 ], i );
                computeCircle( points, edgeIds[ j ], edgeIds[ j + 1 ], i );
            }
            edgeIds.length = 0;
            
        }
        id0 = points.length - 3;
        id1 = points.length - 2;
        id2 = points.length - 1;
        for ( i = 0; i < indices.length; i+= 3 )
        {
            if ( indices[ i ] == id0 || indices[ i ] == id1 || indices[ i ] == id2 
            ||     indices[ i + 1 ] == id0 || indices[ i + 1 ] == id1 || indices[ i + 1 ] == id2 
            ||     indices[ i + 2 ] == id0 || indices[ i + 2 ] == id1 || indices[ i + 2 ] == id2 )
            {
                indices.splice( i, 3 );
                i-=3;
                continue;
            }
        }
        points.pop();
        points.pop();
        points.pop();
        return indices;
    }
    
    private function circleContains( circleId:int, p:Point ):Boolean 
    {
        var dx:Number = circles[ circleId ] - p.x;
        var dy:Number = circles[ circleId + 1 ] - p.y;
        return circles[ circleId + 2 ] > dx * dx + dy * dy;
    }
    
    private function computeCircle( points:Vector.<Point>, id0:int, id1:int, id2:int ):void
    {
        var p0:Point = points[ id0 ];
        var p1:Point = points[ id1 ];
        var p2:Point = points[ id2 ];
        var A:Number = p1.x - p0.x;
        var B:Number = p1.y - p0.y;
        var C:Number = p2.x - p0.x;
        var D:Number = p2.y - p0.y;
        var E:Number = A * (p0.x + p1.x) + B * (p0.y + p1.y);
        var F:Number = C * (p0.x + p2.x) + D * (p0.y + p2.y);
        var G:Number = 2.0 * (A * (p2.y - p1.y) - B * (p2.x - p1.x));
        var x:Number = (D * E - B * F) / G;
        circles.push( x );
        var y:Number = (A * F - C * E) / G;
        circles.push( y );
        x -= p0.x;
        y -= p0.y;
        circles.push( x * x + y * y );
    }
    
    public function render( graphics:Graphics, points:Vector.<Point>, indices:Vector.<int> ):void
    {
        var id0:uint, id1:uint, id2:uint;
        for ( var i:int = 0; i < indices.length; i+=3 ) 
        {
            id0 = indices[ i ];
            id1 = indices[ i + 1 ];
            id2 = indices[ i + 2 ];
            graphics.beginFill(FlashTest.colorArray[int((points[id0].x+points[id1].x+points[id2].x)/3)][int((points[id0].y+points[id1].y+points[id2].y)/3)]);
            graphics.moveTo( points[ id0 ].x, points[ id0 ].y );
            graphics.lineTo( points[ id1 ].x, points[ id1 ].y );
            graphics.lineTo( points[ id2 ].x, points[ id2 ].y );
            graphics.lineTo( points[ id0 ].x, points[ id0 ].y );
            graphics.endFill();
        }
    }
}