TerraForged/TerraForgedCore/src/main/java/com/terraforged/core/util/PosIterator.java
2020-01-16 10:06:28 +00:00

131 lines
3.7 KiB
Java

package com.terraforged.core.util;
public class PosIterator {
private final int minX;
private final int minZ;
private final int maxX;
private final int maxY;
private final int maxZ;
private final int size;
private int x;
private int y;
private int z;
private int index = -1;
public PosIterator(int x, int y, int z, int width, int height, int length) {
this.x = x - 1;
this.y = y;
this.z = z;
this.minX = x;
this.minZ = z;
this.maxX = x + width;
this.maxY = y + height;
this.maxZ = z + length;
this.size = (width * height * length) - 1;
}
/**
* Steps the iterator forward one position if there there is a new position within it's x/y/z bounds.
*
* @return true if the an increment was made, false if the maximum x,y,z coord has been reached
*/
public boolean next() {
if (x + 1 < maxX) {
x += 1;
index++;
return true;
}
if (z + 1 < maxZ) {
x = minX;
z += 1;
index++;
return true;
}
if (y + 1 < maxY) {
x = minX - 1;
z = minZ;
y += 1;
return true;
}
return false;
}
public int size() {
return size;
}
public int index() {
return index;
}
public int x() {
return x;
}
public int y() {
return y;
}
public int z() {
return z;
}
/**
* Iterates over a 2D area in the x-z planes, centered on x:z, with the given radius
*
* Iteration Order:
* 1. Increments the x-axis from x - radius to x + radius (inclusive), then:
* 2. Increments the z-axis once, resets the x-axis to x - radius, then:
* 3. Repeats steps 1 & 2 until z reaches z + radius
*/
public static PosIterator radius2D(int x, int z, int radius) {
int startX = x - radius;
int startZ = z - radius;
int size = radius * 2 + 1;
return new PosIterator(startX, 0, startZ, size, 0, size);
}
/**
* Iterates over a 3D volume, centered on x:y:z, with the given radius
*
* Iteration Order:
* 1. Increments the x-axis (starting from x - radius) up to x + radius (inclusive), then:
* 2. Increments the z-axis once (starting from z - radius) and resets the x-axis to x - radius, then:
* 3. Increments the y-axis once (starting from y - radius), resets the x & z axes to x - radius & z - radius
* respectively, then:
* 4. Repeats steps 1-3 until y reaches y + radius
*/
public static PosIterator radius3D(int x, int y, int z, int radius) {
int startX = x - radius;
int startY = y - radius;
int startZ = z - radius;
int size = radius * 2 + 1;
return new PosIterator(startX, startY, startZ, size, size, size);
}
public static PosIterator area(int x, int z, int width, int length) {
return new PosIterator(x, 0, z, width, 0, length);
}
public static PosIterator volume3D(int x, int y, int z, int width, int height, int length) {
return new PosIterator(x, y, z, width, height, length);
}
public static PosIterator range2D(int minX, int minZ, int maxX, int maxZ) {
int width = maxX - minX;
int length = maxZ - minZ;
return new PosIterator(minX, 0, minZ, width, 0, length);
}
public static PosIterator range2D(int minX, int minY, int minZ, int maxX, int maxY, int maxZ) {
int width = 1 + maxX - minX;
int height = 1 + maxY - minY;
int length = 1 + maxZ - minZ;
return new PosIterator(minX, minY, minZ, width, height, length);
}
}