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

Hilbert Scan

The Hilbert curve has been applied to image processing as a scanning technique (Hilbert scan). 
This scan is guided by the Hilbert space filling curve. 

see also:
  http://en.wikipedia.org/wiki/Hilbert_curve
  http://rest-term.com/archives/1204/

スキャンオーダーにヒルベルト曲線を利用
8次で空間充填、ヒルベルトスキャン
/**
 * Copyright wellflat ( http://wonderfl.net/user/wellflat )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/7qCc
 */

package {
  import flash.system.LoaderContext;
  import flash.net.URLRequest;
  import com.bit101.components.HSlider;
  import com.bit101.components.PushButton;
  import flash.display.*;
  import flash.events.Event;
  import flash.events.MouseEvent;
  import flash.text.*;

  [SWF(width = "465", height = "465", backgroundColor = "#333333", frameRate = "12")]
  
  public class Main extends Sprite { 
    private var hilbert:HilbertScanView;
    private var base:BitmapData;
    private var cover:BitmapData;
    private var tf:TextField;
    private var iter:uint = 0;
    private var slider:HSlider;
    private var button:PushButton;
    private var loaderA:Loader;
    private var loaderB:Loader;
    private var loadedImage:uint = 0;
    
    public function Main() {
      graphics.beginFill(0x333333);
      graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
      graphics.endFill();
      var urlA:String = "http://assets.wonderfl.net/images/related_images/5/56/5609/56092450a3c04a561fe0bfae3338c59cb035d2ac";
      var urlB:String = "http://assets.wonderfl.net/images/related_images/c/cf/cf27/cf27879c502f10c504e40f97151b0430dc11bf5b";
      loaderA = new Loader();
      loaderA.load(new URLRequest(urlA), new LoaderContext(true));
      loaderA.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompleteA);
      loaderB = new Loader();
      loaderB.load(new URLRequest(urlB), new LoaderContext(true));
      loaderB.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompleteB);
      tf = new TextField();
      tf.autoSize = TextFieldAutoSize.LEFT;
      tf.defaultTextFormat = new TextFormat("Courier New", 14, 0xcccccc, true);
      tf.x = 10;
      tf.y = 270;
      tf.text = "Hilbert Order: 0";
      addChild(tf);
      slider = new HSlider(this, 150, 275);
      slider.minimum = 0;
      slider.maximum = 8;
      slider.tick = 1;
      slider.addEventListener(Event.CHANGE, onSliderChange);
      button = new PushButton(this, 150, 300);
      button.label = "Tiffany to Lenna";
      button.addEventListener(MouseEvent.MOUSE_DOWN, onButtonDown);
    }
    private function onCompleteA(e:Event):void {
      var bmpData:BitmapData = new BitmapData(256, 256, false);
      bmpData.draw(loaderA);
      base = bmpData;
      loadedImage++;
      if(loadedImage == 2) {
        createHilbert();
      }
    }
    private function onCompleteB(e:Event):void {
      var bmpData:BitmapData = new BitmapData(256, 256, false);
      bmpData.draw(loaderB);
      cover = bmpData;
      loadedImage++;
      if(loadedImage == 2) {
        createHilbert();
      }
    }
    private function createHilbert():void {
      hilbert = new HilbertScanView(0, cover, base);
      addChild(hilbert);
    }
    private function onSliderChange(e:Event):void {
      var order:uint = e.target.value;
      if(0 <= order && order <= 8) {
        if(hilbert != null){
          hilbert.dispose();
          removeChild(hilbert);
        }
        if(order != 8) tf.text = "Hilbert Order: " + order;
        else tf.text = "Hilbert Scan";
        hilbert = new HilbertScanView(order, cover, base);
        addChild(hilbert);
      }
    }
    private function onButtonDown(e:MouseEvent):void {
      iter = 0;
      stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);      
    }
    private function onEnterFrame(e:Event):void {
      slider.value = iter;
      if(iter != 8) tf.text = "Hilbert Order: " + iter;
      else tf.text = "Hilbert Scan";
      if(iter >= 8) {
        stage.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
      }
      if(hilbert != null){
        hilbert.dispose();
        removeChild(hilbert);
      }
      hilbert = new HilbertScanView(iter, cover, base);
      addChild(hilbert);
      iter++;
    }
  }   
}


  import flash.display.*;
  import flash.geom.Point;

  class HilbertScanView extends Sprite {
    private var order:int;
    private var h:Number;
    private var pt:Point;
    private var bmp:BitmapData;
    private var tmp:BitmapData;
    private var dst:Bitmap;
    
    public function HilbertScanView(order:uint, cover:BitmapData, base:BitmapData) {
      bmp = base.clone();
      tmp = cover;
      order = order;
      pt = new Point();
      dst = new Bitmap();
      h = 1;
      for(var i:int = 2; i <= order; i++) h = h/(2 + h);
      h *= cover.width;
      bmp.lock();
      rightUpLeft(order);  // start path "コ"
      bmp.unlock();
      dst.bitmapData = bmp.clone();
      addChild(dst);
      bmp.dispose();
    }
    public function dispose():void {
      dst.bitmapData.dispose();
    }
    private function rightUpLeft(i:int):void {
      if(i == 0) return;
      upRightDown(i - 1);  scanRelative( h, 0);
      rightUpLeft(i - 1);  scanRelative( 0, h);
      rightUpLeft(i - 1);  scanRelative(-h, 0);
      downLeftUp(i - 1);
    }
    private function downLeftUp(i:int):void {
      if(i == 0) return;
      leftDownRight(i - 1);  scanRelative( 0, -h);
      downLeftUp(i - 1);     scanRelative(-h,  0);
      downLeftUp(i - 1);     scanRelative( 0,  h);
      rightUpLeft(i - 1);
    }
    private function leftDownRight(i:int):void {
      if(i == 0) return;
      downLeftUp(i - 1);     scanRelative(-h,  0);
      leftDownRight(i - 1);  scanRelative( 0, -h);
      leftDownRight(i - 1);  scanRelative( h,  0);
      upRightDown(i - 1);
    }
    private function upRightDown(i:int):void {
      if(i == 0) return;
      rightUpLeft(i - 1);    scanRelative( 0,  h);
      upRightDown(i - 1);    scanRelative( h,  0);
      upRightDown(i - 1);    scanRelative( 0, -h);
      leftDownRight(i - 1);
    }
    private function scanRelative(dx:int, dy:int):void {
      if(dx < 0) {
        for(var x:int = 0; x >= dx; x--) {
          bmp.setPixel(pt.x + x, pt.y, tmp.getPixel(pt.x + x, pt.y));
        }
      } else if(dy < 0) {
        for(var y:int = 0; y >= dy; y--){
          bmp.setPixel(pt.x, pt.y + y, tmp.getPixel(pt.x, pt.y + y));
        }
      } else {
        for(var ay:int = 0; ay <= dy; ay++) {
          for(var ax:int = 0; ax <= dx; ax++) {
            bmp.setPixel(pt.x + ax, pt.y + ay, tmp.getPixel(pt.x + ax, pt.y + ay));
          }
        }
      }
      pt.x += dx;
      pt.y += dy;
    }
  }