So here is the issue I have taken the Doug Moore code from http://www.tiac.net/~sw/2008/10/Hilbert/moore/hilbert.c and converted it into java for use in my masters thesis on implementing an LSH method for storing photons in a Photon Mapped Ray racer. But here in lies the problem. Because of the way that I am utilizing the Hilbert indexes later in my process thresholds are being used. But the the thresholds are lining up with the cracks in the Hilbert curve and causing artifacts in my final image. According to the research I have done the solution to this is to rotate the Hilbert Curve Space about the primary axis slightly but I have no clue as to how to accomplish this. If anyone has any thoughts about this I am extremely stuck at the moment and could use some help.
temp = photonsBH[i].key = h.hilbert_c2i(THREE, SIXTEEN, coord); this line is how i call the hilbert function it takes in 3 params first is the number of dimension, second is the number of bits, and third is the point which has been sent though the following equation to preserve accuracy and shift the point positive.
xi = (int) (EPSILONSHIFT * photonsBH[i].pos[0]) + XYZ_shift[0];
yi = (int) (EPSILONSHIFT * photonsBH[i].pos[1]) + XYZ_shift[1];
zi = (int) (EPSILONSHIFT * photonsBH[i].pos[2]) + XYZ_shift[2];
coord[0] = new BigInteger("" + xi);
coord[1] = new BigInteger("" + yi);
coord[2] = new BigInteger("" + zi);
Code from hilbert.java
public class hilbert
{
// BigInteger bitmask_t;
// BigInteger halfmask_t;
public int size;
public hilbert(int s)
{
size = s;
}
/*
* #define adjust_rotation(rotation,nDims,bits) \ do { \ // rotation =
* (rotation + 1 + ffs(bits)) % nDims; \ bits &= -bits & nd1Ones; \ while
* (bits) \ bits >>= 1, ++rotation; \ if ( ++rotation >= nDims ) \ rotation
* -= nDims; \ } while (0)
*/
public BigInteger adjust_rotation(BigInteger rotation, BigInteger nDims,
BigInteger bits, BigInteger nd1Ones)
{
bits = bits.and(nd1Ones.and(bits.negate()));
while (bits.signum() > 0)
{
bits = bits.shiftRight(1);
rotation = rotation.add(BigInteger.ONE);
}
if ((rotation = rotation.add(BigInteger.ONE)).compareTo(nDims) >= 0)
{
rotation = rotation.subtract(nDims);
}
return rotation;
}
// #define ones(T,k) ((((T)2) << (k-1)) - 1)
public BigInteger ones(BigInteger k)
{
BigInteger r = new BigInteger("2");
r = r.shiftLeft(k.subtract(BigInteger.ONE).intValue());
r = r.subtract(BigInteger.ONE);
// System.out.println("r:" + r);
return r;
}
// #define rdbit(w,k) (((w) >> (k)) & 1)
public BigInteger rdbit(BigInteger w, BigInteger k)
{
BigInteger r = w;
r = r.shiftRight(k.intValue());
r = r.and(BigInteger.ONE);
return r;
}
// #define rotateRight(arg, nRots, nDims) ((((arg) >> (nRots)) | ((arg) <<
// ((nDims)-(nRots)))) & ones(bitmask_t,nDims))
public BigInteger rotateRight(BigInteger arg, BigInteger nRots,
BigInteger nDims)
{
BigInteger r1 = arg.shiftRight(nRots.intValue());
BigInteger r2 = nDims.subtract(nRots);
BigInteger r3 = arg.shiftLeft(r2.intValue());
BigInteger r4 = r1.or(r3);
BigInteger r5 = r4.and(ones(nDims));
return r5;
}
// #define rotateLeft(arg, nRots, nDims) ((((arg) << (nRots)) | ((arg) >>
// ((nDims)-(nRots)))) & ones(bitmask_t,nDims))
public BigInteger rotateLeft(BigInteger arg, BigInteger nRots,
BigInteger nDims)
{
BigInteger r1 = arg.shiftLeft(nRots.intValue());
BigInteger r2 = nDims.subtract(nRots);
BigInteger r3 = arg.shiftRight(r2.intValue());
BigInteger r4 = r1.or(r3);
BigInteger r5 = r4.and(ones(nDims));
return r5;
}
public BigInteger bitTranspose(BigInteger nDims, BigInteger nBits,
BigInteger inCoords)
{
BigInteger nDims1 = nDims.subtract(BigInteger.ONE);
BigInteger inB = nBits;
BigInteger utB;
BigInteger inFieldEnds = BigInteger.ONE;
BigInteger inMask = ones(inB);
BigInteger coords = BigInteger.ZERO;
while ((utB = (inB.divide(new BigInteger("2")))).compareTo(BigInteger.ZERO) != 0)
{
BigInteger shiftAmt = nDims1.multiply(utB);
BigInteger utFieldEnds = inFieldEnds.or((inFieldEnds.shiftLeft((shiftAmt.add(utB)).intValue())));
BigInteger utMask = utFieldEnds.shiftLeft(utB.intValue()).subtract(utFieldEnds);
BigInteger utCoords = BigInteger.ZERO;
BigInteger d;
if ((inB.and(BigInteger.ONE)).compareTo(BigInteger.ZERO) > 0)
{
BigInteger inFieldStarts = inFieldEnds.shiftLeft((inB.subtract(BigInteger.ONE)).intValue());
BigInteger oddShift = shiftAmt.multiply(new BigInteger("2"));
for (d = BigInteger.ZERO; d.compareTo(nDims) < 0; d = d.add(BigInteger.ONE))
{
BigInteger in = inCoords.and(inMask);
inCoords = inCoords.shiftRight(inB.intValue());
BigInteger x1 = in.and(inFieldStarts);
BigInteger x3 = x1.shiftLeft(oddShift.intValue());
oddShift = oddShift.add(BigInteger.ONE);
coords = coords.or(x3);
in = in.and(inFieldStarts.not());
in = (in.or(in.shiftLeft(shiftAmt.intValue()))).and(utMask);
utCoords = utCoords.or(in.shiftLeft((d.multiply(utB)).intValue()));
}
}
else
{
for (d = BigInteger.ZERO; d.compareTo(nDims) < 0; d = d.add(BigInteger.ONE))
{
BigInteger in = inCoords.and(inMask);
inCoords = inCoords.shiftRight(inB.intValue());
in = (in.or(in.shiftLeft(shiftAmt.intValue()))).and(utMask);
utCoords = utCoords.or(in.shiftLeft((d.multiply(utB)).intValue()));
}
}
inCoords = utCoords;
inB = utB;
inFieldEnds = utFieldEnds;
inMask = utMask;
}
coords = coords.or(inCoords);
return coords;
}
/*****************************************************************
* hilbert_i2c
*
* Convert an index into a Hilbert curve to a set of coordinates. Inputs:
* nDims: Number of coordinate axes. nBits: Number of bits per axis. index:
* The index, contains nDims*nBits bits (so nDims*nBits must be <=
* 8*sizeof(bitmask_t)). Outputs: coord: The list of nDims coordinates, each
* with nBits bits. Assumptions: nDims*nBits <= (sizeof index) *
* (bits_per_byte)
*/
public double[] hilbert_i2c(BigInteger nDims, BigInteger nBits,BigInteger index)
{
double[] coord = new double[3];
if (nDims.intValue() > 1)
{
BigInteger coords;
BigInteger nbOnes = ones(nBits);
if (nBits.compareTo(BigInteger.ONE) > 0)
{
BigInteger nDimsBits = nDims.multiply(nBits);
BigInteger ndOnes = ones(nDims);
BigInteger nd1Ones = ndOnes.shiftRight(1);
BigInteger b = nDimsBits;
BigInteger rotation = BigInteger.ZERO;
BigInteger flipBit = BigInteger.ZERO;
BigInteger nthbits = ones(nDimsBits).divide(ndOnes);
index = index.xor((index.xor(nthbits).shiftRight(1)));
coords = BigInteger.ZERO;
do
{
BigInteger bits = index.shiftRight((b = b.subtract(nDims)).intValue()).and(ndOnes);
coords = coords.shiftLeft(nDims.intValue());
coords = coords.or(rotateLeft(bits, rotation, nDims).xor(flipBit));
flipBit = (BigInteger.ONE).shiftLeft(rotation.intValue());
rotation = adjust_rotation(rotation, nDims, bits, nd1Ones);
} while (b.intValue() > 0);
for (b = nDims; b.compareTo(nDimsBits) < 0; b = b.multiply(new BigInteger("2")))
{
BigInteger c1 = coords.shiftRight(b.intValue());
coords = coords.xor(c1);
}
coords = bitTranspose(nBits, nDims, coords);
}
else
{
coords = index.xor(index.shiftRight(1));
}
for (int i = 0; i < coord.length; i++)
{
coord[i] = coords.and(nbOnes).doubleValue();
coords = coords.shiftRight(nBits.intValue());
}
}
else
{
coord[0] = index.doubleValue();
}
return coord;
}
/*****************************************************************
* hilbert_c2i
*
* Convert coordinates of a point on a Hilbert curve to its index. Inputs:
* nDims: Number of coordinates. nBits: Number of bits/coordinate. coord:
* Array of n nBits-bit coordinates. Outputs: index: Output index value.
* nDims*nBits bits. Assumptions: nDims*nBits <= (sizeof bitmask_t) *
* (bits_per_byte)
*/
public BigInteger hilbert_c2i(BigInteger nDims, BigInteger nBits,BigInteger[] coord)
{
if (nDims.compareTo(BigInteger.ONE) > 0)
{
BigInteger index;
BigInteger nDimsBits = nDims.multiply(nBits);
BigInteger d;
BigInteger coords = BigInteger.ZERO;
for (int i = nDims.intValue(); i > 0; i--)
{
coords = coords.shiftLeft(nBits.intValue());
coords = coords.or(coord[i - 1]);
}
if (nBits.compareTo(BigInteger.ONE) > 0)
{
BigInteger ndOnes = ones(nDims);
BigInteger nd1Ones = ndOnes.shiftRight(1);
BigInteger b = nDimsBits;
BigInteger rotation = BigInteger.ZERO;
BigDecimal rotation2 = new BigDecimal(""+ (-45.0 * (Math.PI/180)));
BigInteger flipBit = BigInteger.ZERO;
BigInteger nthBits = ones(nDimsBits).divide(ndOnes);
coords = bitTranspose(nDims, nBits, coords);
coords = coords.xor(coords.shiftRight(nDims.intValue()));
index = BigInteger.ZERO;
do
{
BigInteger bits = coords.shiftRight((b = b.subtract(nDims)).intValue()).and(ndOnes);
bits = rotateRight((flipBit.xor(bits)), rotation, nDims);
index = index.shiftLeft(nDims.intValue());
index = index.or(bits);
flipBit = (BigInteger.ONE).shiftLeft(rotation.intValue());
rotation = adjust_rotation(rotation, nDims, bits, nd1Ones);
} while (b.compareTo(BigInteger.ZERO) > 0);
index = index.xor(nthBits.shiftRight(1));
}
else
{
index = coords;
}
for (d = BigInteger.ONE; d.compareTo(nDimsBits) < 0; d = d.multiply(new BigInteger("2")))
{
index = index.xor((index.shiftRight(d.intValue())));
}
return index;
}
else
return coord[0];
}
}