added math, Split BitRegion into BitRegion3D and BitRegion2D

reordered parameters to allow for a superclass. 2d and 3d have
different numbers of parameters, so ordered them so they could be input
as an int… array
This commit is contained in:
BuildTools 2017-01-24 18:34:46 -05:00
parent a21af80204
commit 592b3ca0f3
2 changed files with 488 additions and 262 deletions

View file

@ -0,0 +1,366 @@
package regions;
import java.util.BitSet;
public class BitRegion2D
{
/*
CONSTRUCTORS
*/
protected int[] sides; public int[] getSides() { return sides; }
protected final BitSet blocks;
public BitRegion2D()
{
sides = new int[] { 0, 0 };
blocks = new BitSet();
}
/*
GET VALUE
*/
/**
* Get number of blocks contained in the region.
*/
public int getVolume()
{
return blocks.cardinality();
}
/**
* Get number of blocks contained in the region's bounding box.
*/
public int getBoundsVolume()
{
return (sides[0]) * (sides[1]);
}
/**
* Get coordinates for the block at the given index in the BitSet.
*
* @param index
* @return
*/
protected int[] getCoords(int index)
{
if (index++ == 0) return new int[] {0, 0};
int[] xz = new int[2];
xz[1] = index / sides[0]; if ((index = index % sides[0]) == 0) { xz[1] -= 1; index = sides[0]; }
xz[0] = index - 1;
return xz;
}
/**
* Get the index within the internal BitSet for the given coordinates.
*
* @param coordinate
* @return
*/
public int getIndex(int x, int z)
{
return (z * sides[0]) + x;
}
/**
* Returns whether or not region contains the block at the given coordinates.
*
* @param x
* @param z
* @return
*/
public boolean contains(int x, int z)
{
if (0 > x || x >= sides[0] ||
0 > z || z >= sides[1])
return false;
return blocks.get(getIndex(x,z));
}
/**
* Returns the value for this index within the internal BitSet.
*
* @param index
* @return
*/
public boolean bitvalue(int index)
{
return blocks.get(index);
}
/*
OPERATIONS
*/
/**
*
* @param shift
* @param fromIndex
*/
public void bitshift(int shift, int fromIndex)
{
if (shift < 1) return;
int toAboveThisIndex = fromIndex + shift - 1;
for (int i = blocks.size() + shift; i > toAboveThisIndex; i--)
blocks.set(i, blocks.get(i - shift));
blocks.clear(fromIndex, toAboveThisIndex);
}
/**
*
* @param xShift
* @param zShift
* @param yShift
*/
public void expand(int xMin, int xMax, int zMin, int zMax)
{
int[] newSides = new int[] {xMax - xMin + 1,
zMax - zMin + 1};
/* add empty space before each x row
* add empty space at bottom
*/
}
/**
*
* @param x
* @param z
*/
public void adjustBoundsIfNecessary(int x, int z)
{
if (-1 < x && x < sides[0] &&
-1 < z && z < sides[1])
return;
int bX = sides[0] - 1;
int bZ = sides[1] - 1;
expand( x < 0 ? x : 0,
x > bX ? x : bX,
z < 0 ? z : 0,
z > bZ ? z : bZ);
}
/**
*
* @param minX
* @param minZ
* @param maxX
* @param maxZ
*/
public void adjustBoundsIfNecessary(int minX, int maxX, int minZ, int maxZ)
{
if (-1 < minX && maxX < sides[0] &&
-1 < minZ && maxZ < sides[1])
return;
int bX = sides[0] - 1;
int bZ = sides[1] - 1;
expand( minX < 0 ? minX : 0,
maxX > bX ? maxX : bX,
minZ < 0 ? minZ : 0,
maxZ > bZ ? maxZ : bZ);
}
/*-------------------------------------
OVERLOADS : fill()
-------------------------------------*/
/**
*
*/
public void fill()
{
blocks.set(0, getBoundsVolume() - 1);
}
/**
*
* @param x
* @param z
*/
public void fill(int x, int z)
{
adjustBoundsIfNecessary(x, z);
blocks.set(getIndex(x, z));
}
/**
*
*
* @param minX
* @param minZ
* @param maxX
* @param maxZ
*/
public void fill(int minX, int maxX, int minZ, int maxZ)
{
adjustBoundsIfNecessary(minX, maxX, minZ, maxZ);
int z;
int x;
int index;
for (z = minZ; z <= maxZ; z++)
{
index = getIndex(minX, z);
for (x = minX; x <= maxX; x++)
{
blocks.set(index++);
}
}
}
/**
*
* @param blocksToFill
* @param minX
* @param minZ
* @param maxX
* @param maxZ
*/
public void fill(BitSet blocksToFill, int minX, int maxX, int minZ, int maxZ)
{
adjustBoundsIfNecessary(minX, maxX, minZ, maxZ);
int z;
int x;
int index1;
int index2 = 0;
for (z = minZ; z <= maxZ; z++)
{
index1 = getIndex(minX, z);
for (x = minX; x <= maxX; x++)
{
if (blocksToFill.get(index2++)) blocks.set(index1++);
}
}
}
/*-------------------------------------
OVERLOADS : clear()
-------------------------------------*/
/**
*
*/
public void clear()
{
blocks.clear();
}
/**
*
* @param x
* @param z
*/
public void clear(int x, int z)
{
blocks.clear(getIndex(x, z));
}
/**
*
*
* @param minX
* @param minZ
* @param maxX
* @param maxZ
*/
public void clear(int minX, int maxX, int minZ, int maxZ)
{
int z;
int x;
int index;
for (z = minZ; z <= maxZ; z++)
{
index = getIndex(minX, z);
for (x = minX; x <= maxX; x++)
{
blocks.clear(index++);
}
}
}
/**
*
* @param blocksToClear
* @param minX
* @param minZ
* @param maxX
* @param maxZ
*/
public void clear(BitSet blocksToClear, int minX, int maxX, int minZ, int maxZ)
{
int z;
int x;
int index1;
int index2 = 0;
for (z = minZ; z <= maxZ; z++)
{
index1 = getIndex(minX, z);
for (x = minX; x <= maxX; x++)
{
if (blocksToClear.get(index2++)) blocks.clear(index1++);
}
}
}
}

View file

@ -2,7 +2,7 @@ package regions;
import java.util.BitSet;
public class BitRegion
public class BitRegion3D
{
/*
@ -15,39 +15,15 @@ public class BitRegion
protected int[] sides; public int[] getSides() { return sides; }
public final boolean is3D;
protected final BitSet blocks;
protected BitRegion(int xSideLength, int zSideLength)
protected BitRegion3D()
{
sides = new int[] { xSideLength, zSideLength };
is3D = false;
sides = new int[] { 0, 0, 0 };
blocks = new BitSet();
}
protected BitRegion(int xSideLength, int zSideLength, int ySideLength)
{
sides = new int[] { xSideLength, zSideLength, ySideLength };
is3D = true;
blocks = new BitSet();
}
public static BitRegion new2DBitRegion()
{
return new BitRegion(0, 0);
}
public static BitRegion new3DBitRegion()
{
return new BitRegion(0, 0, 0);
}
/*
@ -60,7 +36,7 @@ public class BitRegion
/**
* Get number of blocks contained in the region
* Get number of blocks contained in the region.
*/
public int getVolume()
{
@ -69,138 +45,88 @@ public class BitRegion
/**
* Get number of blocks contained in the region's bounding box
* Get number of blocks contained in the region's bounding box.
*/
public int getBoundsVolume()
{
return is3D ?
(sides[0]) * (sides[1]) * (sides[2]) :
(sides[0]) * (sides[1]);
return (sides[0]) * (sides[1]) * (sides[2]);
}
/**
* Get coordinates for the block at the given index in the BitSet
*
* @param index
* @return
*/
protected int[] getCoords(int index)
{
if (++index > getBoundsVolume()) return null;
return is3D ?
getCoords3D(index) :
getCoords2D(index);
}
/**
*
* Get coordinates for the block at the given index in the BitSet.
*
* @param index
* @return
*/
protected int[] getCoords3D(int index)
{
if (index == 0) return new int[] {0, 0, 0};
if (index++ == 0) return new int[] {0, 0, 0};
int[] xzy = new int[3];
int crossSec = sides[0] * sides[1];
xzy[2] = index / crossSec - ((index = index % crossSec) == 0 ? 1 : 0); index = (index == 0 ? crossSec : index);
xzy[1] = index / sides[0] - ((index = index % sides[0]) == 0 ? 1 : 0); index = (index == 0 ? sides[0] : index);
xzy[2] = index / crossSec; if ((index = index % crossSec) == 0) { xzy[2] -= 1; index = crossSec; }
xzy[1] = index / sides[0]; if ((index = index % sides[0]) == 0) { xzy[1] -= 1; index = sides[0]; }
xzy[0] = index - 1;
return xzy;
}
/**
*
* @param index
* @return
*/
protected int[] getCoords2D(int index)
{
if (index == 0) return new int[] {0, 0};
int[] xz = new int[2];
xz[1] = index / sides[0] - ((index = index % sides[0]) == 0 ? 1 : 0); index = (index == 0 ? sides[0] : index);
xz[0] = index - 1;
return xz;
}
/*-------------------------------------
OVERLOADS : getIndex()
-------------------------------------*/
/**
* Get the index within the internal BitSet for the given coordinates.
*
* @param coordinate
* @return
*/
public int getIndex(int x, int z)//TODO return -1 if outside bounds
{
return (z * sides[0]) + x;
}
/**
*
* @param coordinate
* @return
*/
public int getIndex(int x, int z, int y)//TODO return -1 if outside bounds
protected int getIndex(int x, int z, int y)
{
return (y * sides[0] * sides[1]) + (z * sides[0]) + x;
}
/*-------------------------------------
OVERLOADS : blockAt()
-------------------------------------*/
/**
*
* @param x
* @param z
* @return
*/
public boolean blockAt(int x, int z)//TODO return false if outside bounds
{
return blocks.get(getIndex(x,z));
}
/**
* Returns whether or not region contains the block at the given coordinates.
*
* @param x
* @param z
* @param y
* @return
*/
public boolean blockAt(int x, int z, int y)//TODO return false if outside bounds
public boolean contains(int x, int z, int y)
{
if (0 > x || x >= sides[0] ||
0 > z || z >= sides[1] ||
0 > y || y >= sides[2])
return false;
return blocks.get(getIndex(x, z, y));
}
/**
* Returns the value for this index within the internal BitSet.
*
* @param index
* @return
*/
public boolean blockAt(int index)
public boolean bitvalue(int index)
{
return blocks.get(index);
}
/*----------------------------------------------------------------------------
------------------------------------------------------------------------------
OVERLOADS : shift()
------------------------------------------------------------------------------
----------------------------------------------------------------------------*/
/*
OPERATIONS
*/
/**
@ -214,36 +140,94 @@ public class BitRegion
int toAboveThisIndex = fromIndex + shift - 1;
for (int i = blocks.size() + shift; i > toAboveThisIndex; i++)
{
for (int i = blocks.size() + shift; i > toAboveThisIndex; i--)
blocks.set(i - shift, blocks.get(i));
}
blocks.clear(fromIndex, toAboveThisIndex);
}
public void shift(int xShift, int zShift)
/**
*
* @param xShift
* @param zShift
* @param yShift
*/
public void expand(int xMin, int xMax, int zMin, int zMax, int yMin, int yMax)
{
int[] newSides = new int[] {xMax - xMin + 1,
zMax - zMin + 1,
yMax - yMin + 1};
/* add empty space before each x row
* add empty space at bottom
*/
}
/**
*
* @param x
* @param z
* @param y
*/
public void adjustBoundsIfNecessary(int x, int z, int y)
{
if (-1 < x && x < sides[0] &&
-1 < z && z < sides[1] &&
-1 < y && y < sides[2])
return;
int bX = sides[0] - 1;
int bZ = sides[1] - 1;
int bY = sides[2] - 1;
expand( x < 0 ? x : 0,
x > bX ? x : bX,
z < 0 ? z : 0,
z > bZ ? z : bZ,
y < 0 ? y : 0,
y > bY ? y : bY);
}
/**
*
* @param minX
* @param minZ
* @param minY
* @param maxX
* @param maxZ
* @param maxY
*/
public void adjustBoundsIfNecessary(int minX, int minZ, int minY, int maxX, int maxZ, int maxY)
{
if (-1 < minX && maxX < sides[0] &&
-1 < minZ && maxZ < sides[1] &&
-1 < minY && maxY < sides[2])
return;
int bX = sides[0] - 1;
int bZ = sides[1] - 1;
int bY = sides[2] - 1;
expand( minX < 0 ? minX : 0,
maxX > bX ? maxX : bX,
minZ < 0 ? minZ : 0,
maxZ > bZ ? maxZ : bZ,
minY < 0 ? minY : 0,
maxY > bY ? maxY : bY);
}
public void shift(int xShift, int zShift, int yShift)
{
}
/*----------------------------------------------------------------------------
------------------------------------------------------------------------------
/*-------------------------------------
OVERLOADS : fill()
------------------------------------------------------------------------------
----------------------------------------------------------------------------*/
-------------------------------------*/
/**
*
*/
@ -253,17 +237,6 @@ public class BitRegion
}
/**
*
* @param x
* @param z
*/
public void fill(int x, int z)
{
blocks.set(getIndex(x, z));
}
/**
*
* @param x
@ -272,6 +245,8 @@ public class BitRegion
*/
public void fill(int x, int z, int y)
{
adjustBoundsIfNecessary(x, z, y);
blocks.set(getIndex(x, z, y));
}
@ -281,37 +256,15 @@ public class BitRegion
*
* @param minX
* @param minZ
* @param minY
* @param maxX
* @param maxZ
* @param maxY
*/
public void fill(int minX, int minZ, int maxX, int maxZ)//TODO adjust bounds if necessary
public void fill(int minX, int maxX, int minZ, int maxZ, int minY, int maxY)
{
int z;
int x;
adjustBoundsIfNecessary(minX, maxX, minZ, maxZ, minY, maxY);
int index;
for (z = minZ; z <= maxZ; z++)
{
index = getIndex(minX, z);
for (x = minX; x <= maxX; x++)
{
blocks.set(index++);
}
}
}
/**
*
*
* @param minX
* @param minZ
* @param maxX
* @param maxZ
*/
public void fill(int minX, int minZ, int minY, int maxX, int maxZ, int maxY)//TODO adjust bounds if necessary
{
int y;
int z;
int x;
@ -334,45 +287,18 @@ public class BitRegion
/**
*
*
* @param minX
* @param minZ
* @param maxX
* @param maxZ
* @param blocksToFill
*/
public void fill(int minX, int minZ, int maxX, int maxZ, BitSet blocksToFill)//TODO adjust bounds if necessary
{
int z;
int x;
int index1;
int index2 = 0;
for (z = minZ; z <= maxZ; z++)
{
index1 = getIndex(minX, z);
for (x = minX; x <= maxX; x++)
{
if (blocksToFill.get(index2++)) blocks.set(index1++);
}
}
}
/**
*
*
* @param minX
* @param minZ
* @param minY
* @param maxX
* @param maxZ
* @param maxY
* @param blocksToFill
*/
public void fill(int minX, int minZ, int minY, int maxX, int maxZ, int maxY, BitSet blocksToFill)//TODO adjust bounds if necessary
public void fill(BitSet blocksToFill, int minX, int maxX, int minZ, int maxZ, int minY, int maxY)
{
adjustBoundsIfNecessary(minX, maxX, minZ, maxZ, minY, maxY);
int y;
int z;
int x;
@ -395,11 +321,9 @@ public class BitRegion
/*----------------------------------------------------------------------------
------------------------------------------------------------------------------
/*-------------------------------------
OVERLOADS : clear()
------------------------------------------------------------------------------
----------------------------------------------------------------------------*/
-------------------------------------*/
/**
@ -411,17 +335,6 @@ public class BitRegion
}
/**
*
* @param x
* @param z
*/
public void clear(int x, int z)
{
blocks.clear(getIndex(x, z));
}
/**
*
* @param x
@ -439,36 +352,12 @@ public class BitRegion
*
* @param minX
* @param minZ
* @param minY
* @param maxX
* @param maxZ
* @param maxY
*/
public void clear(int minX, int minZ, int maxX, int maxZ)
{
int z;
int x;
int index;
for (z = minZ; z <= maxZ; z++)
{
index = getIndex(minX, z);
for (x = minX; x <= maxX; x++)
{
blocks.clear(index++);
}
}
}
/**
*
*
* @param minX
* @param minZ
* @param maxX
* @param maxZ
*/
public void clear(int minX, int minZ, int minY, int maxX, int maxZ, int maxY)
public void clear(int minX, int maxX, int minZ, int maxZ, int minY, int maxY)
{
int y;
int z;
@ -492,44 +381,15 @@ public class BitRegion
/**
*
*
* @param minX
* @param minZ
* @param maxX
* @param maxZ
* @param blocksToClear
*/
public void clear(int minX, int minZ, int maxX, int maxZ, BitSet blocksToClear)
{
int z;
int x;
int index1;
int index2 = 0;
for (z = minZ; z <= maxZ; z++)
{
index1 = getIndex(minX, z);
for (x = minX; x <= maxX; x++)
{
if (blocksToClear.get(index2++)) blocks.clear(index1++);
}
}
}
/**
*
*
* @param minX
* @param minZ
* @param minY
* @param maxX
* @param maxZ
* @param maxY
* @param blocksToClear
*/
public void clear(int minX, int minZ, int minY, int maxX, int maxZ, int maxY, BitSet blocksToClear)
public void clear(BitSet blocksToClear, int minX, int maxX, int minZ, int maxZ, int minY, int maxY)
{
int y;
int z;