Scrambler
1
|
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) |
void closedformhilbert2d | ( | int * | nn, |
int * | rr, | ||
int * | cc, | ||
int * | hh | ||
) |
Definition at line 30 of file hilbert.bg.c.
Referenced by DistributionControl::HilbertValue().
{ 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.bg.c.
Referenced by DistributionControl::HilbertValue().
{ 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; }