From 592b3ca0f32e7d7e04117711df7ad88d283f3467 Mon Sep 17 00:00:00 2001 From: BuildTools Date: Tue, 24 Jan 2017 18:34:46 -0500 Subject: [PATCH] added math, Split BitRegion into BitRegion3D and BitRegion2D MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- src/regions/BitRegion2D.java | 366 +++++++++++++++++ .../{BitRegion.java => BitRegion3D.java} | 384 ++++++------------ 2 files changed, 488 insertions(+), 262 deletions(-) create mode 100644 src/regions/BitRegion2D.java rename src/regions/{BitRegion.java => BitRegion3D.java} (53%) diff --git a/src/regions/BitRegion2D.java b/src/regions/BitRegion2D.java new file mode 100644 index 0000000..4ee8555 --- /dev/null +++ b/src/regions/BitRegion2D.java @@ -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++); + } + } + } +} diff --git a/src/regions/BitRegion.java b/src/regions/BitRegion3D.java similarity index 53% rename from src/regions/BitRegion.java rename to src/regions/BitRegion3D.java index c3c3fbc..2a57428 100644 --- a/src/regions/BitRegion.java +++ b/src/regions/BitRegion3D.java @@ -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;