|
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;
}
Here is the caller graph for this function:| 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;
}
Here is the caller graph for this function: