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

2Dメタボール(マーチングキューブ法)

2Dメタボール
Get Adobe Flash player
by Nao_u 20 Apr 2009
// 
// 2Dメタボール
// 
package {     
    import flash.display.Sprite;     
    import flash.events.*;     
    [SWF(width="465", height="465", backgroundColor="0xFFFFFF", frameRate="60")]      
    public class FlashTest extends Sprite {     
        public function FlashTest() {     
            Main = this;     
            initialize();     
            stage.addEventListener(Event.ENTER_FRAME,update);      
        }     
    }     
}    

import flash.display.*; 
import flash.text.*; 
import flash.events.*;     
import flash.geom.*;  
var SCREEN_W:Number = 465, SCREEN_H:Number = 465;    
var Main:Sprite;     
var Text:TextField    
var BmpData: BitmapData;  
var Bmp: Bitmap;  


var WIDTH:int = 128;
var Scale:Number = 7.5 * 0.5;    
var BITMAP_W:int = WIDTH; 
var BITMAP_H:int = WIDTH; 
var Threshold:int = 0.0;

var PointAry:Vector.<EdgePoint> = new Vector.<EdgePoint>;
var BallAry:Vector.<Ball> = new Vector.<Ball>;

function initialize():void{     
    Text = new TextField();     
    Text.text = "test";   
    Text.autoSize = "left";   
    Main.addChild(Text);      

    BmpData = new BitmapData(BITMAP_W, BITMAP_H, false, 0x000000);  
    Bmp = new Bitmap(BmpData);  
    Bmp.scaleX = 0.5; 
    Bmp.scaleY = 0.5; 
    Main.addChild(Bmp);      

    for( var y:int=0; y<WIDTH; y++ ){
        for( var x:int=0; x<WIDTH; x++ ){
            var idx:int = x + y * WIDTH;
            PointAry[idx] = new EdgePoint(x, y);
            PointAry[idx].Value = -1.25 + 1/4.0 * Math.sqrt( (x-3.5) * (x-3.5) + (y-4.5) * (y-4.5) );
        }
    }
    
    for( var i:int=0; i<35; i++){
        BallAry.push( new Ball( 0, 0, Math.random()*0.75, Math.random()*0.75, 3+Math.random()*25 ) );
    }
}


function update(e :Event):void{     
    graphicClear();

 
    var shape:Shape = new Shape(); 
    var g:Graphics = shape.graphics; 
    g.beginFill( 0x0000, 1 );     
    g.drawRect( 0, 0, WIDTH, WIDTH );
    g.endFill();     
    BmpData.draw(shape); 

    for each ( var ball:Ball in BallAry ) ball.update();

    for each ( var pnt:EdgePoint in PointAry ) {
        var col:int = BmpData.getPixel( pnt.x, pnt.y );
        pnt.Value = (col&0xff) / 127.0 - 0.5;
        //pnt.draw();
    }


    for( var y:int=0; y<WIDTH-1; y++ ){
        for( var x:int=0; x<WIDTH-1; x++ ){
            var idx0:int =  x    +  y    * WIDTH;
            var idx1:int = (x+1) +  y    * WIDTH;
            var idx2:int =  x    + (y+1) * WIDTH;
            var idx3:int = (x+1) + (y+1) * WIDTH;
            test( PointAry[idx0], PointAry[idx1], PointAry[idx2], PointAry[idx3] );
        }
    }

}  

function test( p0:EdgePoint, p1:EdgePoint, p2:EdgePoint, p3:EdgePoint ):void{
    var type:int = 0;
    if( p0.Value > Threshold ) type += 1;
    if( p1.Value > Threshold ) type += 2;
    if( p2.Value > Threshold ) type += 4;
    if( p3.Value > Threshold ) type += 8;

    switch( type ){
    case  0:    break;
    case  1:    drawType0( p0, p1, p2 ); break;
    case  2:    drawType0( p1, p3, p0 ); break;    
    case  3:    drawType1( p0, p1, p2, p3 ); break;
    case  4:    drawType0( p2, p3, p0 ); break; 
    case  5:    drawType1( p0, p2, p1, p3 ); break;
    case  6:    drawType0( p0, p1, p2 ); drawType0( p1, p3, p0 ); break;
    case  7:    drawType2( p3, p1, p2 ); break;
    case  8:    drawType0( p3, p1, p2 ); break;
    case  9:    drawType0( p0, p1, p2 ); drawType0( p3, p1, p2 ); break;
    case 10:    drawType1( p1, p3, p0, p2 ); break;
    case 11:    drawType2( p2, p0, p3 ); break;
    case 12:    drawType1( p2, p3, p0, p1 ); break;
    case 13:    drawType2( p1, p0, p3 ); break;
    case 14:    drawType2( p0, p1, p2 ); break;
    case 15:    break;
    }
}


class Ball{  
    public var X:Number, Y:Number; 
    public var Sx:Number, Sy:Number; 
    public var R:Number; 
    public function Ball( x:Number, y:Number, sx:Number, sy:Number, r:Number ){  
        X = x;
        Y = y;
        Sx = sx;
        Sy = sy;
        R = r;
    }  

    public function update():void{
        X += Sx;
        Y += Sy;
        if( X < 0 ) Sx *= -1;
        if( Y < 0 ) Sy *= -1;
        if( X > WIDTH ) Sx *= -1;
        if( Y > WIDTH ) Sy *= -1;
        drawGradientCircleBmp( BmpData, X, Y, R, 0x606060, 0x000000 );
    }
}  

class EdgePoint{  
    public var x:Number, y:Number; 
    public var Value:Number; 
    public function EdgePoint( rx:Number, ry:Number ){  
        x = rx;
        y = ry;
    }  
    public function draw():void{
        drawPoint( x, y, 0x000000 );
    }
}  

function drawType0( p0:EdgePoint, p1:EdgePoint, p2:EdgePoint ):void{
    var pv0:Point = new Point, pv1:Point = new Point;
    var vec0:Point = new Point, vec1:Point = new Point;
    var ratio0:Number = p0.Value / (p0.Value - p1.Value);
    var ratio1:Number = p0.Value / (p0.Value - p2.Value);

    vec0.x = p1.x - p0.x;
    vec0.y = p1.y - p0.y;
    vec1.x = p2.x - p0.x;
    vec1.y = p2.y - p0.y;
    
    pv0.x = p0.x + vec0.x * ratio0;
    pv0.y = p0.y + vec0.y * ratio0;
    pv1.x = p0.x + vec1.x * ratio1;
    pv1.y = p0.y + vec1.y * ratio1;
    drawLine( pv0.x, pv0.y, pv1.x, pv1.y, 1, 0xff0000 );
}

function drawType1( p0:EdgePoint, p1:EdgePoint, p2:EdgePoint, p3:EdgePoint ):void{
    var pv0:Point = new Point, pv1:Point = new Point;
    var vec0:Point = new Point, vec1:Point = new Point;
    var ratio0:Number = p0.Value / (p0.Value - p2.Value);
    var ratio1:Number = p1.Value / (p1.Value - p3.Value);

    vec0.x = p2.x - p0.x;
    vec0.y = p2.y - p0.y;
    vec1.x = p3.x - p1.x;
    vec1.y = p3.y - p1.y;
    
    pv0.x = p0.x + vec0.x * ratio0;
    pv0.y = p0.y + vec0.y * ratio0;
    pv1.x = p1.x + vec1.x * ratio1;
    pv1.y = p1.y + vec1.y * ratio1;
    drawLine( pv0.x, pv0.y, pv1.x, pv1.y, 1, 0xff0000 );
}

function drawType2( p3:EdgePoint, p1:EdgePoint, p2:EdgePoint ):void{
    var pv0:Point = new Point, pv1:Point = new Point;
    var vec0:Point = new Point, vec1:Point = new Point;
    var ratio0:Number = p3.Value / (p3.Value - p1.Value);
    var ratio1:Number = p3.Value / (p3.Value - p2.Value);

    vec0.x = p1.x - p3.x;
    vec0.y = p1.y - p3.y;
    vec1.x = p2.x - p3.x;
    vec1.y = p2.y - p3.y;
    
    pv0.x = p3.x + vec0.x * ratio0;
    pv0.y = p3.y + vec0.y * ratio0;
    pv1.x = p3.x + vec1.x * ratio1;
    pv1.y = p3.y + vec1.y * ratio1;
    drawLine( pv0.x, pv0.y, pv1.x, pv1.y, 1, 0xff0000 );
}

function graphicClear():void{   
    Main.graphics.clear();    
}   

function drawLine( sx:Number, sy:Number, ex:Number, ey:Number, size:Number, col:int ):void{     
    Main.graphics.lineStyle(size,col);
    Main.graphics.moveTo( Scale*sx, Scale*sy );        
    Main.graphics.lineTo( Scale*ex, Scale*ey);           
} 

function drawCircle( x:Number, y:Number, size:Number, col:int ):void{     
    Main.graphics.lineStyle(1.0,0x000000);        
    Main.graphics.beginFill( col, 1 );     
    Main.graphics.drawCircle( Scale*x, Scale*y, Scale*size );     
    Main.graphics.endFill();     
}    

function drawPoint( x:Number, y:Number, col:int ):void{     
    Main.graphics.lineStyle(1.0,0x000000);        
    Main.graphics.beginFill( col, 1 );     
    Main.graphics.drawRect( Scale*x, Scale*y, 1, 1 );
    Main.graphics.endFill();     
}    

function drawGradientCircleBmp( bmpData:BitmapData, x0:Number, y0:Number, r:Number, col0:int, col1:int ):void{
var matrix:Matrix = new Matrix();
    var shape:Shape = new Shape(); 
    var g:Graphics = shape.graphics; 
    var mtx:Matrix; 
    matrix.createGradientBox( 1, 1, 0, -0.5, -0.5 );
    var vx0:Number = r;
    var vy0:Number = 0;
    var vx1:Number = 0;
    var vy1:Number = r;
    var cx:Number = x0;
    var cy:Number = y0;
    matrix.concat( new Matrix( vx0*2, vy0*2, vx1*2, vy1*2, cx, cy ) );

    g.clear(); 
    g.beginGradientFill(GradientType.RADIAL, [col0,col1], [1,1], [0,255], matrix); 
    g.drawCircle(cx, cy, r ); 
    g.endFill(); 
    bmpData.draw(shape, null, null, BlendMode.ADD); 
}