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

文字のShape化

ビットマップデータの2値化、
頂点の抽出、
リンクリストの作成、
リンクリストのVector化、
いらない頂点の消去
を順番に行っています。
Get Adobe Flash player
by shohei909 16 Jan 2011
  • Related works: 1
  • Talk

    makc3d at 16 Jan 2011 05:47
    shouldn't if( s <= size ) be if( min <= size )?
    whaison at 16 Jan 2011 07:10
    これって極めると 中村Yugoppさんの 踊るフォントサービスへ向かってる方向ですよねー! 勇吾さんが FITCでいっていた。やつ。。。
    shohei909 at 16 Jan 2011 08:55
    >>makc3d Thank you! I corrected! >>whasion 知らなかったので、調べてみました。 フォントが音楽に合わせてウゴウゴするやつですね。 フォントをウゴウゴさせるのはやりたいと思っていました。 でも、向こうの場合は塗りじゃなくて線でフォントを表現してたので、 また違う方法でやってるみたいでした。 うーん・・・興味深い。

    Tags

    Embed
/**
 * Copyright shohei909 ( http://wonderfl.net/user/shohei909 )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/nt3v
 */

package {
    import flash.display.Graphics;
    import flash.text.TextFormat;
    import flash.display.Bitmap;
    import flash.text.TextField;
    import flash.display.BitmapData;
    import flash.events.Event;
    import flash.display.Sprite;
    import flash.display.Shape;
    import flash.utils.setInterval;
    import flash.utils.getTimer;
    
    public class FlashTest extends Sprite {
        public const W:int = 155;
        public const H:int = 60;
        
        public var map:Vector.<Vector.<Anchor>> = new Vector.<Vector.<Anchor>>();
        public var vec:Vector.<Anchor> = new Vector.<Anchor>();
        public var paths:Vector.<Vector.<Anchor>> = new Vector.<Vector.<Anchor>>();
        
        public var shape:Shape = new Shape();
        public var guide:Shape = new Shape();
        public var bitmapData:BitmapData = new BitmapData( W, H );
       
        public function FlashTest() {
            var text:TextField = new TextField()
            text.defaultTextFormat = new TextFormat( "", 55 );
            text.width = W;
            text.height= H;
            text.text = "Orz";
            bitmapData.draw( text );
            
            var bmp:Bitmap = new Bitmap( bitmapData );
            shape.scaleX = shape.scaleY = guide.scaleX = guide.scaleY = bmp.scaleX = bmp.scaleY = 3;
            addChild( bmp ).y = 0 ;
            addChild( guide ).y = 150;
            addChild( shape ).y = 300;
            
            for( var i:int = 0; i < W+1; i++ ){ 
                map[i] = new Vector.<Anchor>();
                for( var j:int = 0; j < H+1; j++ ){
                    map[i][j] = null;
                }
            }
            progress();
        }
        
        
        public function progress():void{
            var time:int = getTimer();
            var c:int = 0;
            monoColor();
            setVec();
            setLink();
            draw();
            setPaths();
            cutAnchors();
            drawShape()
        }
        
        
        public function draw():void{
            var g:Graphics = guide.graphics;
            g.clear();
            g.lineStyle( 0.5, 0xFF0000 );
            for each( var a:Anchor in vec ){ 
                g.drawCircle( a.x, a.y, 0.5 );
                var nx:Anchor = a.next;
                if( nx ){
                    g.moveTo( a.x, a.y );
                    g.lineTo( nx.x, nx.y );
                }
            }
        }
        
        public function drawShape():void{
            var g:Graphics = shape.graphics;
            g.clear();
            g.lineStyle( 0.5, 0, 1 );
            g.beginFill( 0xFF2222, 1 );
            for each( var v:Vector.<Anchor> in paths ){
                var l:int = v.length
                var a1:Anchor = v[l-2];
                var a2:Anchor = v[l-1];
                var a3:Anchor = v[0];
                g.moveTo( a2.x, a2.y )
                
                for( var i:int = 1; i<l; i++ ){
                    a1 = a2;
                    a2 = a3;
                    a3 = v[i];
                    g.lineTo( a2.x, a2.y )
                }
            }
        }

        

        
        public function monoColor():void {
            var b:BitmapData = this.bitmapData;
            b.lock();
            for( var x:int = 0; x < W; x++ ){
                for( var y:int = 0; y < H; y++ ){
                    if( b.getPixel( x, y ) != 0xFFFFFF ){ b.setPixel( x, y, 0 ) }                
                }                
            }
            b.unlock();
        }
        public function setVec():void {
            var b:BitmapData = this.bitmapData;
            for( var x2:int = 0; x2 < W; x2++ ){
                for( var y2:int = 0; y2 < H; y2++ ){
                    var d:Array = []; 
                    var dl:int = 0; 
                    for( var dx:int = -1; dx < 1; dx++ ){ 
                        for( var dy:int = -1; dy < 1; dy++ ){ 
                            var x:int = x2 + dx;
                            var y:int = y2 + dy;
                            if( x < 0 || W+1 < x || y < 0 || H+1 < y || b.getPixel(x,y) != 0 ){ d.push( "0" ) }
                            else { d.push( "1" ); dl++ }
                        }    
                    }
                    if( dl == 1 || dl == 3 ){
                        var dir:Array;
                        if( dl == 1 ){ 
                            dir = [ [0,-1],[-1,0],[1,0],[0,1] ][ d.indexOf("1") ]
                        }else{
                            dir = [ [-1,0],[0,1],[0,-1],[1,0] ][ d.indexOf("0") ]
                        }
                        var anc:Anchor = new Anchor( x2, y2, dir );
                        vec.push( anc );
                        map[x2][y2] = anc;
                    }
                }                
            }
        }
        public function setLink():void{
            for each( var a:Anchor in vec ){
                var dx:int = a.dir[0];
                var dy:int = a.dir[1];
                var x:int = a.x;
                var y:int = a.y;
                while( true ){
                    x += dx; y += dy;
                    if( x < 0 || W < x || y < 0 || H < y  ){ break }
                    if( map[x][y] != null ){ a.next = map[x][y]; break; }             
                }
            }
        }
        public function setPaths():void{
            while( vec.length > 0 ){
                var first:Anchor = vec[0];
                var a:Anchor = first;
                var v:Vector.<Anchor> = new Vector.<Anchor>; 
                do{
                    v.push(a)
                    vec.splice( vec.indexOf(a), 1 );
                    a = a.next;
                }while( first != a )
                paths.push( v );
            }
        }
        public function cutAnchors( size:Number = 0.7 ):void{
            for each( var v:Vector.<Anchor> in paths ){
                while( v.length > 3 ){
                    var l:int = v.length
                    var a1:Anchor = v[l-2];
                    var a2:Anchor = v[l-1];
                    var a3:Anchor = v[0];
                    var min:Number = getTriangleHeight( a1, a2, a3 );
                    var mp:int = l-1;
                    for( var i:int = 1; i<l; i++ ){
                        a1 = a2;
                        a2 = a3;
                        a3 = v[i];
                        var s:Number = getTriangleHeight( a1, a2,  a3 );
                        if( s < min ){ min = s; mp = i-1; }
                    }
                    if( min < size ){
                        v.splice( mp, 1 );
                    }else{ break; }
                }
            }
        }
        private function getTriangleHeight( a1:Anchor, a2:Anchor, a3:Anchor ):Number{
            var x:Number = a3.x - a1.x ; var y:Number = a3.y - a1.y ;
            var s:Number = ( a2.x - a1.x ) * y - ( a2.y - a1.y ) * x ;
            var l:Number = Math.sqrt(x*x + y*y)
            return ( s > 0 ? s : -s ) / l / 2;
        }
    }
}

class Anchor{
    public var x:Number;
    public var y:Number;
    public var dir:Array;
    public var next:Anchor;
    public var curve:Number = 0;
    
    function Anchor(x:Number,y:Number,dir:Array){ this.x = x; this.y = y; this.dir = dir }
}