<?php
class hilbert_square {
public static $Directions = array(
'west' => array( 'north', 'east', 'west', 'south', 'west', 'west', 'south' ),
'east' => array( 'south', 'west', 'east', 'north', 'east', 'east', 'north' ),
'north' => array( 'west', 'south', 'north', 'east', 'north', 'north', 'east' ),
'south' => array( 'east', 'north', 'south', 'west', 'south', 'south', 'west' )
);
public $scale;
public $level;
public $callback;
private $x;
private $y;
public function __construct($length, $callback){
$this->level = sqrt(intval($length));
$this->scale = 1;
$this->callback = $callback;
$this->x = 0;
$this->y = 0;
if(!is_callable($this->callback)) exit('hilbert_cube: callback argument is not a function');
}
private function walk($direction){
switch($direction){
case 'north':
$this->y -= $this->scale;
break;
case 'south':
$this->y += $this->scale;
break;
case 'east':
$this->x += $this->scale;
break;
case 'west':
$this->x -= $this->scale;
break;
}
//echo "\n$direction - ", $this->x, ',', $this->y;
call_user_func($this->callback, $this->x, $this->y);
}
private function hilbert($level, $direction='north'){
$dirs = self::$Directions[$direction];
for($i=0;$i<6;$i+=2){
if($level != 1){
$hbResult = $this->hilbert($level-1,$dirs[$i]);
if($hbResult){
return $hbResult;
}
}
$moveResult = $this->walk($dirs[$i+1]);
if($moveResult){
// A non-false return from either function means
// we've found our target, so we can break out
// of the recursion.
return $moveResult;
}
}
if($level != 1) {
$hbResult = $this->hilbert($level-1, $dirs[6]);
if($hbResult){
return $hbResult;
}
}
return false;
}
public function run(){
call_user_func($this->callback, $this->x, $this->y);
$this->hilbert($this->level);
}
}
?>