Scrambler  1
hilbert.c File Reference

Contains routines for calculating hilbert values. More...

Go to the source code of this file.

Functions/Subroutines

void closedformhilbert2d_ (int *nn, int *rr, int *cc, int *hh)
void closedformhilbert3d_ (int *nn, int *rr, int *cc, int *dd, int *hh)

Detailed Description

Contains routines for calculating hilbert values.

Definition in file hilbert.c.


Function/Subroutine Documentation

void closedformhilbert2d_ ( int *  nn,
int *  rr,
int *  cc,
int *  hh 
)

Definition at line 30 of file hilbert.c.

                                                                   {
  unsigned h=0;
  unsigned ri=0;
  unsigned ci=0;
  unsigned pos; 
  unsigned mask; 
  unsigned i, tmp;
  unsigned n;
  unsigned r;
  unsigned c;
  n = *nn;
  r = *rr;
  c = *cc;

  // In 2D the hilbert curve looks like
  //    ___
  //   |   |  Ordering for cases  2  4   Hilbert Order       1  2
  //   |   |  ----------------->  1  3   ----------------->  0  3

  //                      
  //   __    __                  __    __
  //  |  |__|  |  4 sub pieces  |  |  |  |  2    4  | 2 is in standard orientation
  //  |__    __|   -------->     __    __           | 4 is also instandard orientation
  //   __|  |__                  __|  |__   1    3  | 1 needs to be flipped about x=y 
  //                                                | 3 needs to be flipped about x=-y

  // Basic idea is to coarsen hilbert curve out to get the 
  // meta position which determins the case and the coarse "meta" hilbert value
  // Then depending on which case, re-orient the sub grid so that it is in standard 
  // orientation.  Then multiply the meta hilbert value by 4 before adding the next 
  // level value and so on...

  // example n=3, r=4=100 ,c=5=101
  // pos=100
  // mask=011

  // i=0-> ri=001, ci=001 -> case 4 (meta hilbert value = 2)
  // ri->1, ci->0
  // r=000, c=001
  // h=10
  // pos=010
  // mask=001

  // i=1-> ri=000, ci=000 -> case 1 (meta hilbert value = 0)
  // ri->0, ci->0
  // r=001, c=000
  // h=1000
  // pos=001
  // mask=000

  // i=2-> ri=1, ci=0 -> case 3 (meta hilbert value = 3)
  // ri->1, ci->1
  // r=000, c=000
  // h=100011
  // pos=000
  // mask=000

  //hilbert value = 100011 = 35

  pos = 1 << (n-1);           // bit mask used to extract ri and ci which are meta positions of the coarsened hilbert curve
  mask = pow(2,(n-1))-1;      // 0001111111 mask used to subtract off ci and ri to get relative positions within the coarsened hilbert curve
  for (i=0; i<n; i++) {

    ri = (r & pos) >> (n-i-1);   // meta row position of coarsened hilbert curve
    ci = (c & pos) >> (n-i-1);   // meta column position of coarsened hilbert curve
    r = r & mask; c = c & mask;  // local row and column positions within the current section of the meta hilbert curve

    if (ri==0 && ci==0) {               // Case 1 (Lower left corner)
      ri = 0; ci = 0;                   //  meta hilbert value = 0 -> 00 in binary  
      tmp = r; r = c; c = tmp; }        // In order to rotate the next meta hilbert tree into standard order we need to reflect about x=y or swap r and c
    else if (ri==0 && ci==1) {          // Case 2 (Upper Left corner)
      ri = 0; ci = 1; }                 // meta hilbert value = 1 -> 01 in binary (already in standard order)
    else if (ri==1 && ci==0) {          // Case 3 (Lower right corner)
      ri = 1; ci = 1;                   // meta hilbert value = 3 -> 11 in binary
      tmp = r; r = c; c = tmp;          // Need to rotate -90 and reflect in x (x->-y->-y, y->x->-x) or (x=-y, y=-x)
      r = ~r & mask; c = ~c & mask; }   // to arrange in standard order
    else {                              // Case 4 (Upper right corner)
      ri = 1; ci = 0; }                 // meta hilbert value = 2 -> 10 in binary (Already in standard order)

    pos = pos >> 1; mask = mask >> 1;   // shift pos and mask to next finer level of hilbert fractal
    h = (((h << 1) | ri) << 1) | ci;    // multiply h by 4 and add contribution from meta hilbert value
  }
  *hh=h;
}
void closedformhilbert3d_ ( int *  nn,
int *  rr,
int *  cc,
int *  dd,
int *  hh 
)

Definition at line 116 of file hilbert.c.

                                                                             {
  unsigned h=0;
  unsigned ri;
  unsigned ci;
  unsigned di;
  unsigned pos; 
  unsigned mask; 
  unsigned i, tmp;
  unsigned n;
  unsigned r;
  unsigned c;
  unsigned d;
  n = *nn;
  r = *rr;
  c = *cc;
  d = *dd;

  // And In 3D the hilbert curve looks like
  //    ____
  //   /   /  Ordering for cases  5  7    Hilbert Order     6  5
  //  / __/_  -----------------> 4  6   -----------------> 7  4
  //   / | /  ----------------->  1  3  ----------------->  1  2
  //  /  |/                      0  2                      0  3


  // I won't draw the second generation hilbert curve - but basic idea is the same for 2D.
  // For each case add the appropriate hilbert value based on the hilbert order
  // Then reorient the subsection into standard orientation using flips/rotations etc...
  // The second generation hilbert curve was taken from Space Filling Curves by ...

  h=0;

  pos = 1 << (n-1);           // bit mask used to extract ri and ci which are meta positions of the coarsened hilbert curve
  mask = pow(2,(n-1))-1;      // 0001111111 mask used to subtract off ci and ri to get relative positions within the coarsened hilbert curve
  for (i=0; i<n; i++) {
    ri = (r & pos) >> (n-i-1);   // meta row position of coarsened hilbert curve
    ci = (c & pos) >> (n-i-1);   // meta column position of coarsened hilbert curve
    di = (d & pos) >> (n-i-1);   // meta depth position
    r = r & mask; c = c & mask; d = d & mask;  // local row and column positions within the current section of the meta hilbert curve
    if (di==0 && ri==0 && ci==0) {                        // Case 1 (Bottom-Front-Left corner)
      di = 0; ri = 0; ci = 0;                             // meta hilbert value = 0 -> 000 in binary        
      tmp = c; c = d; d = tmp; }                          // Need to reflect around c=d

    else if (di==0 && ri==0 && ci==1) {                   // Case 2 (Bottom-Back-Left corner)
      di = 0; ri = 0; ci = 1;                             // meta hilbert value = 1 -> 001 in binary (already in standard order) 
      tmp = r; r = d; d = tmp; }                          // Need to reflect about r=d

    else if (di==0 && ri==1 && ci==0) {                   // Case 3 (Bottom-Front-Right corner)
      di = 0; ri = 1; ci = 1;                             // meta hilbert value = 3 -> 011 in binary
      tmp = r; r = ~c & mask; c = ~d & mask ; d = tmp;}   // need to rotate about [r,-c,d]

    else if (di==0 && ri==1 && ci==1) {                   // Case 4 (Bottom-Back-Right)
      di = 0; ri = 1; ci = 0; }                           // meta hilbert value = 2 -> 010 in binary (Already in standard order)

    else if (di==1 && ri==0 && ci==0) {                   // Case 5 (Top-Front-Left corner)
      di = 1; ri = 1; ci = 1;                             // meta hilbert value = 7 -> 111 in binary  
      tmp = c; c = ~d & mask; d = ~tmp & mask;}           // Need to reflect about c=-d


    else if (di==1 && ri==0 && ci==1) {                   // Case 6 (Top-Back-Left)
      di = 1; ri = 1; ci = 0;                             // meta hilbert value = 6 -> 110 in binary (already in standard order)
      tmp = r; r=~d & mask; d=~tmp & mask; }              // Need to reflect about d=-r

    else if (di==1 && ri==1 && ci==0) {                   // Case 7 (Top-Front-Right corner)
      di = 1; ri = 0; ci = 0;                             // meta hilbert value = 4 -> 100 in binary
      tmp = d; d = ~r & mask; r = ~c & mask; c = tmp;}    // Need to reflect about c=-r and then reflect about c=d

    else {// (di==1 && ri==1 && ci==1)                    // Case 8 (Top-Back-Right corner)
      di = 1; ri = 0; ci = 1; }                           // meta hilbert value = 5 -> 101 in binary (Already in standard order)

    pos = pos >> 1; mask = mask >> 1;                     // shift pos and mask to next finer level of hilbert fractal
    h = ((((h << 1) | di) << 1) | ri) << 1 | ci;          // multiply h by 8 and add contribution from meta hilbert value
  }
  *hh=h;
}
 All Classes Files Functions Variables