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

PerlinNoiseのリアルタイムアニメーション

PerlinNoise生成
高速化テスト中。
とりあえず関数を展開。
修正:CatmullRom補間 を cos補間 に変更、約2倍高速化
// forked from Nao_u's PerlinNoise生成
// 
// PerlinNoise生成
//   高速化テスト中。
//   とりあえず関数を展開。
// 
// 修正:CatmullRom補間 を cos補間 に変更、約2倍高速化
// 

package {     
    import flash.display.Sprite;     
    import flash.events.*;     
    [SWF(width="465", height="465", backgroundColor="0xFFFFFF", frameRate="15")]
        
    public class FlashTest extends Sprite {     
        public function FlashTest() {     
            Main = this;     
            initialize();     
            stage.addEventListener(Event.ENTER_FRAME,update);      
        }     
    }     
}             
    
import flash.display.Bitmap; 
import flash.display.BitmapData; 
import flash.display.Sprite;      
import flash.events.*
import flash.text.TextField;     
import flash.geom.*;
import flash.utils.getTimer;
var Main:Sprite;     
var SCREEN_W:Number = 465;
var SCREEN_H:Number = 465;
var Text:TextField    
var View: Bitmap; 
var BmpData: BitmapData; 

var BITMAP_W:int = SCREEN_W/4;
var BITMAP_H:int = SCREEN_H/4;

function initialize():void{     
    BmpData = new BitmapData(BITMAP_W, BITMAP_H, false, 0xffffff); 
    View = new Bitmap(BmpData); 
    View.x = 64.0;
    View.y = 64.0;
    View.scaleX = 3.0;
    View.scaleY = 3.0;
    Main.addChild(View);      

    Text = new TextField();     
    Text.text = "PerlinNoise生成中...";   
    Text.autoSize = "left";
    Main.addChild(Text);      

    makeRndTbl();
}

var Cnt:int;
function update(e :Event):void{     
    Cnt++;
    var px:Number = Cnt * 1.40 + 1.1 * Math.cos(Cnt*0.003);
    var py:Number = Cnt * 0.45 + 0.25 * Math.cos(Cnt*0.1);
    //if( (Cnt & 0x01) == 0 )
    {
        var time:int = getTimer(); 
        var mul:Number = 180;
        BmpData.lock(); 
        for( var x:int=0; x<BITMAP_W; x++ ){ 
            for( var y:int=0; y<BITMAP_H; y++ ){ 
                var col:int = PerlinNoiseCos( x, y, px, py, 16.0, 0.35, 3 ) * mul;
                col = col + 128;
                col = col + (col<<8) + (col<<16);
                BmpData.setPixel(x, y, col); 
            }
        } 
        BmpData.unlock(); 

        var endTime:int = getTimer() - time;
        Text.text = "生成時間:" + endTime + "[ms]";   
    }
}  

// PerlinNoiseを生成(cos補間を使用)
function PerlinNoiseCos( rx:Number, ry:Number, sx:Number, sy:Number, frequency:Number, presistence:Number, octave:int ):Number{
    var total:Number = 0;
    var amplitude:Number = presistence;

    for( var i:int=0; i<octave; i++ ){
        var x:Number = rx/frequency + sx/(frequency*0.1+5);
        var y:Number = ry/frequency + sy/(frequency*0.01+4);
        var ix:int = x;
        var iy:int = y;
        var tx:Number = (x - ix);
        var ty:Number = (y - iy);

       var ix_0 :int = (ix  )&0xff;
       var ix_1 :int = (ix+1)&0xff;
       var iy_0 :int = ((iy  )&0xff)*RNDTBL_SIZE;
       var iy_1 :int = ((iy+1)&0xff)*RNDTBL_SIZE;
   
        var a:Number, b:Number, t:Number;
        var ft:Number, f:Number;
        a = RndTbl[ ix_0 + iy_0];
        b = RndTbl[ ix_1 + iy_0];
        t = tx;
        ft = t * Math.PI;
        f  = (1.0 - Math.cos( ft )) * 0.5;
        var x0:Number = a * (1.0 - f) + b * f;

        a = RndTbl[ ix_0 + iy_1];
        b = RndTbl[ ix_1 + iy_1];
        t = tx;
        ft = t * Math.PI;
        f  = (1.0 - Math.cos( ft )) * 0.5;
        var y0:Number = a * (1.0 - f) + b * f;

        a = x0;
        b = y0;
        t = ty;
        ft = t * Math.PI;
        f  = (1.0 - Math.cos( ft )) * 0.5;
        total += (a * (1.0 - f) + b * f) * amplitude;
        
        amplitude *= presistence;
        frequency *= 0.5;
    }

    return total;
}

// 入力値( x, y ) に対応した、-1.0 ~ 1.0 の擬似乱数を生成
function rnd( x:int, y:int ):Number{
    x += y * 465 + 789221;
    x = (x>>10) ^ x;
    var ret:int = (( (x * (x * x * 15731 + 789221) + 1376312589) ) / 1000000);
    
    return (ret & 0x1ff) / 256 - 1.0;
}

// 256*256のランダムテーブルを生成
var RNDTBL_SIZE:int = 256;
var RndTbl:Vector.<Number> = new Vector.<Number>;
function makeRndTbl():void{
    for( var y:int=0; y<RNDTBL_SIZE; y++ ){
        for( var x:int=0; x<RNDTBL_SIZE; x++ ){
            RndTbl[x + y*RNDTBL_SIZE] = rnd(x,y);
        }
    }
}