3次元ヒルベルト曲線
前回の記事からちょくちょく頑張っていて一応「長さ→座標」部分は出来ました。同じ対応で「座標→長さ」も出来るかと思いきやどうもダメっぽいのでとりあえず諦めました(ぉ
class HilbertCurve3 { public: HilbertCurve3( int order ):m_order(order){} virtual ~HilbertCurve3(){} int GetAllCount()const{ const int size = GetSize(); return size * size * size; } int GetSize()const{ return 1 << m_order; } void GetPosition( int t, int& x, int& y, int& z ){ x = y = z = 0; for (int order = 0; order < m_order; ++order) { const int s = 1 << order; const int rx = GetPos( 0, t ); const int ry = GetPos( 1, t ); const int rz = GetPos( 2, t ); rotate(s, x, y, z, t & 7); x += s * rx; y += s * ry; z += s * rz; t >>= 3; } } private: int GetPos( unsigned int axis, unsigned int length ){ const int bit2 = ((length & 7 )>> axis); return ((bit2 >> 1 ) ^ bit2) & 1; } void rotate(int n, int& x, int& y, int& z, int t) { if( t < 1 ){ const int i = z; z = y; y = x; x = i; }else if( t < 3 ){ std::swap( y,z ); }else if( t < 5 ){ x = n-1 - x; y = n-1 - y; }else if( t < 7 ){ const int i = n-1 - y; y = n-1 - z; z = i; }else{ const int i = n-1 - z; z = n-1 - y; y = x; x = i; } } private: int m_order; };
結局、苦労したのはrotate部分である。正直言うとここの規則性がどうもわからない。なので4次元以上は不明である。ちなみにGetPosの部分は法則性がわかったので全ての次元で出来る。回転さえわかればなぁ。
まあとはいえ、たとえ分かったとしてもデバッグが死ぬほど大変だと思われる(3次元でもかなり大変だった)のでこのあたりで諦めます。