mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-06-18 06:41:08 +00:00
Advanced mantle editing
This commit is contained in:
@@ -18,8 +18,10 @@
|
||||
|
||||
package com.volmit.iris.util.mantle;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.engine.data.cache.Cache;
|
||||
import com.volmit.iris.engine.object.basic.IrisPosition;
|
||||
import com.volmit.iris.util.collection.KMap;
|
||||
import com.volmit.iris.util.collection.KSet;
|
||||
import com.volmit.iris.util.documentation.BlockCoordinates;
|
||||
@@ -28,17 +30,20 @@ import com.volmit.iris.util.documentation.RegionCoordinates;
|
||||
import com.volmit.iris.util.format.C;
|
||||
import com.volmit.iris.util.format.Form;
|
||||
import com.volmit.iris.util.function.Consumer4;
|
||||
import com.volmit.iris.util.math.INode;
|
||||
import com.volmit.iris.util.math.KochanekBartelsInterpolation;
|
||||
import com.volmit.iris.util.math.M;
|
||||
import com.volmit.iris.util.math.PathInterpolation;
|
||||
import com.volmit.iris.util.matter.Matter;
|
||||
import com.volmit.iris.util.parallel.BurstExecutor;
|
||||
import com.volmit.iris.util.parallel.HyperLock;
|
||||
import com.volmit.iris.util.parallel.MultiBurst;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
@@ -79,6 +84,13 @@ public class Mantle {
|
||||
Iris.debug("Opened The Mantle " + C.DARK_AQUA + dataFolder.getAbsolutePath());
|
||||
}
|
||||
|
||||
/**
|
||||
* Raise a flag if it is lowered currently, If the flag was raised, execute the runnable
|
||||
* @param x the chunk x
|
||||
* @param z the chunk z
|
||||
* @param flag the flag to raise
|
||||
* @param r the runnable to fire if the flag is now raised (and was previously lowered)
|
||||
*/
|
||||
@ChunkCoordinates
|
||||
public void raiseFlag(int x, int z, MantleFlag flag, Runnable r) {
|
||||
if (!hasFlag(x, z, flag)) {
|
||||
@@ -87,6 +99,13 @@ public class Mantle {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lower a flag if it is raised. If the flag was lowered (meaning it was previously raised), execute the runnable
|
||||
* @param x the chunk x
|
||||
* @param z the chunk z
|
||||
* @param flag the flag to lower
|
||||
* @param r the runnable that is fired if the flag was raised but is now lowered
|
||||
*/
|
||||
@ChunkCoordinates
|
||||
public void lowerFlag(int x, int z, MantleFlag flag, Runnable r) {
|
||||
if (hasFlag(x, z, flag)) {
|
||||
@@ -95,11 +114,27 @@ public class Mantle {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flag or unflag a chunk
|
||||
* @param x the chunk x
|
||||
* @param z the chunk z
|
||||
* @param flag the flag
|
||||
* @param flagged should it be set to flagged or not
|
||||
*/
|
||||
@ChunkCoordinates
|
||||
public void flag(int x, int z, MantleFlag flag, boolean flagged) {
|
||||
get(x >> 5, z >> 5).getOrCreate(x & 31, z & 31).flag(flag, flagged);
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate data in a chunk
|
||||
* @param x the chunk x
|
||||
* @param z the chunk z
|
||||
* @param type the type of data to iterate
|
||||
* @param iterator the iterator (x,y,z,data) -> do stuff
|
||||
* @param requiredFlags any required flags that must be met for this chunk to be iterated
|
||||
* @param <T> the type of data to iterate
|
||||
*/
|
||||
@ChunkCoordinates
|
||||
public <T> void iterateChunk(int x, int z, Class<T> type, Consumer4<Integer, Integer, Integer, T> iterator, MantleFlag... requiredFlags) {
|
||||
for (MantleFlag i : requiredFlags) {
|
||||
@@ -111,17 +146,13 @@ public class Mantle {
|
||||
get(x >> 5, z >> 5).getOrCreate(x & 31, z & 31).iterate(type, iterator);
|
||||
}
|
||||
|
||||
@ChunkCoordinates
|
||||
public <T> void iterateChunk(int x, int z, Class<T> type, Consumer4<Integer, Integer, Integer, T> iterator, BurstExecutor e, MantleFlag... requiredFlags) {
|
||||
for (MantleFlag i : requiredFlags) {
|
||||
if (!hasFlag(x, z, i)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
get(x >> 5, z >> 5).getOrCreate(x & 31, z & 31).iterate(type, iterator, e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this chunk have a flag on it?
|
||||
* @param x the x
|
||||
* @param z the z
|
||||
* @param flag the flag to test
|
||||
* @return true if it's flagged
|
||||
*/
|
||||
@ChunkCoordinates
|
||||
public boolean hasFlag(int x, int z, MantleFlag flag) {
|
||||
return get(x >> 5, z >> 5).getOrCreate(x & 31, z & 31).isFlagged(flag);
|
||||
@@ -190,6 +221,10 @@ public class Mantle {
|
||||
.get(x & 15, y & 15, z & 15);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this mantle closed
|
||||
* @return true if it is
|
||||
*/
|
||||
public boolean isClosed()
|
||||
{
|
||||
return closed.get();
|
||||
@@ -367,10 +402,23 @@ public class Mantle {
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file for a region
|
||||
* @param folder the folder
|
||||
* @param x the x coord
|
||||
* @param z the z coord
|
||||
* @return the file
|
||||
*/
|
||||
public static File fileForRegion(File folder, int x, int z) {
|
||||
return fileForRegion(folder, key(x, z));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file for the given region
|
||||
* @param folder the data folder
|
||||
* @param key the region key
|
||||
* @return the file
|
||||
*/
|
||||
public static File fileForRegion(File folder, Long key) {
|
||||
String id = UUID.nameUUIDFromBytes(("TectonicPlate:" + key).getBytes(StandardCharsets.UTF_8)).toString();
|
||||
File f = new File(folder, id.substring(0, 2) + "/" + id.split("\\Q-\\E")[3] + "/" + id + ".ttp");
|
||||
@@ -378,6 +426,12 @@ public class Mantle {
|
||||
return f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the long value representing a chunk or region coordinate
|
||||
* @param x the x
|
||||
* @param z the z
|
||||
* @return the value
|
||||
*/
|
||||
public static Long key(int x, int z) {
|
||||
return Cache.key(x, z);
|
||||
}
|
||||
@@ -385,4 +439,437 @@ public class Mantle {
|
||||
public void saveAll() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a sphere into the mantle
|
||||
* @param cx the center x
|
||||
* @param cy the center y
|
||||
* @param cz the center z
|
||||
* @param radius the radius of this sphere
|
||||
* @param fill should it be filled? or just the outer shell?
|
||||
* @param data the data to set
|
||||
* @param <T> the type of data to apply to the mantle
|
||||
*/
|
||||
public <T> void setSphere(int cx, int cy, int cz, double radius, boolean fill, T data)
|
||||
{
|
||||
setElipsoid(cx, cy, cz, radius, radius, radius, fill, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an elipsoid into the mantle
|
||||
* @param cx the center x
|
||||
* @param cy the center y
|
||||
* @param cz the center z
|
||||
* @param rx the x radius
|
||||
* @param ry the y radius
|
||||
* @param rz the z radius
|
||||
* @param fill should it be filled or just the outer shell?
|
||||
* @param data the data to set
|
||||
* @param <T> the type of data to apply to the mantle
|
||||
*/
|
||||
public <T> void setElipsoid(int cx, int cy, int cz, double rx, double ry, double rz, boolean fill, T data)
|
||||
{
|
||||
rx += 0.5;
|
||||
ry += 0.5;
|
||||
rz += 0.5;
|
||||
final double invRadiusX = 1 / rx;
|
||||
final double invRadiusY = 1 / ry;
|
||||
final double invRadiusZ = 1 / rz;
|
||||
final int ceilRadiusX = (int) Math.ceil(rx);
|
||||
final int ceilRadiusY = (int) Math.ceil(ry);
|
||||
final int ceilRadiusZ = (int) Math.ceil(rz);
|
||||
double nextXn = 0;
|
||||
|
||||
forX: for (int x = 0; x <= ceilRadiusX; ++x) {
|
||||
final double xn = nextXn;
|
||||
nextXn = (x + 1) * invRadiusX;
|
||||
double nextYn = 0;
|
||||
forY: for (int y = 0; y <= ceilRadiusY; ++y) {
|
||||
final double yn = nextYn;
|
||||
nextYn = (y + 1) * invRadiusY;
|
||||
double nextZn = 0;
|
||||
for (int z = 0; z <= ceilRadiusZ; ++z) {
|
||||
final double zn = nextZn;
|
||||
nextZn = (z + 1) * invRadiusZ;
|
||||
|
||||
double distanceSq = lengthSq(xn, yn, zn);
|
||||
if (distanceSq > 1) {
|
||||
if (z == 0) {
|
||||
if (y == 0) {
|
||||
break forX;
|
||||
}
|
||||
break forY;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!fill) {
|
||||
if (lengthSq(nextXn, yn, zn) <= 1 && lengthSq(xn, nextYn, zn) <= 1 && lengthSq(xn, yn, nextZn) <= 1) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
set(x + cx,y + cy,z + cz, data);
|
||||
set(-x + cx,y + cy,z + cz, data);
|
||||
set(x + cx,-y + cy,z + cz, data);
|
||||
set(x + cx,y + cy,-z + cz, data);
|
||||
set(-x + cx,y + cy,-z + cz, data);
|
||||
set(-x + cx,-y + cy,z + cz, data);
|
||||
set(x + cx,-y + cy,-z + cz, data);
|
||||
set(-x + cx,y + cy,-z + cz, data);
|
||||
set(-x + cx,-y + cy,-z + cz, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a cuboid of data in the mantle
|
||||
* @param x1 the min x
|
||||
* @param y1 the min y
|
||||
* @param z1 the min z
|
||||
* @param x2 the max x
|
||||
* @param y2 the max y
|
||||
* @param z2 the max z
|
||||
* @param data the data to set
|
||||
* @param <T> the type of data to apply to the mantle
|
||||
*/
|
||||
public <T> void setCuboid(int x1, int y1, int z1, int x2, int y2, int z2, T data)
|
||||
{
|
||||
int j,k;
|
||||
|
||||
for(int i = x1; i <= x2; i++)
|
||||
{
|
||||
for(j = x1; j <= x2; j++)
|
||||
{
|
||||
for(k = x1; k <= x2; k++)
|
||||
{
|
||||
set(i,j,k,data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a pyramid of data in the mantle
|
||||
* @param cx the center x
|
||||
* @param cy the base y
|
||||
* @param cz the center z
|
||||
* @param data the data to set
|
||||
* @param size the size of the pyramid (width of base & height)
|
||||
* @param filled should it be filled or hollow
|
||||
* @param <T> the type of data to apply to the mantle
|
||||
*/
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
public <T> void setPyramid(int cx, int cy, int cz, T data, int size, boolean filled) {
|
||||
int height = size;
|
||||
|
||||
for (int y = 0; y <= height; ++y) {
|
||||
size--;
|
||||
for (int x = 0; x <= size; ++x) {
|
||||
for (int z = 0; z <= size; ++z) {
|
||||
if ((filled && z <= size && x <= size) || z == size || x == size) {
|
||||
set(x + cx, y + cy, z + cz, data);
|
||||
set(-x + cx, y + cy, z + cz, data);
|
||||
set(x + cx, y + cy, -z + cz, data);
|
||||
set(-x + cx, y + cy, -z + cz, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a 3d tube spline interpolated with Kochanek Bartels
|
||||
* @param nodevectors the vector points
|
||||
* @param radius the radius
|
||||
* @param filled if it should be filled or hollow
|
||||
* @param data the data to set
|
||||
*/
|
||||
public <T> void setSpline(List<Vector> nodevectors, double radius, boolean filled, T data) {
|
||||
setSpline(nodevectors, 0, 0, 0, 10, radius, filled, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a 3d tube spline interpolated with Kochanek Bartels
|
||||
* @param nodevectors the spline points
|
||||
* @param tension the tension 0
|
||||
* @param bias the bias 0
|
||||
* @param continuity the continuity 0
|
||||
* @param quality the quality 10
|
||||
* @param radius the radius
|
||||
* @param filled filled or hollow
|
||||
* @param data the data to set
|
||||
* @param <T> the type of data to apply to the mantle
|
||||
*/
|
||||
public <T> void setSpline(List<Vector> nodevectors, double tension, double bias, double continuity, double quality, double radius, boolean filled, T data) {
|
||||
Set<IrisPosition> vset = new KSet<>();
|
||||
List<INode> nodes = new ArrayList<>(nodevectors.size());
|
||||
PathInterpolation interpol = new KochanekBartelsInterpolation();
|
||||
|
||||
for (Vector nodevector : nodevectors) {
|
||||
INode n = new INode(nodevector);
|
||||
n.setTension(tension);
|
||||
n.setBias(bias);
|
||||
n.setContinuity(continuity);
|
||||
nodes.add(n);
|
||||
}
|
||||
|
||||
interpol.setNodes(nodes);
|
||||
double splinelength = interpol.arcLength(0, 1);
|
||||
for (double loop = 0; loop <= 1; loop += 1D / splinelength / quality) {
|
||||
Vector tipv = interpol.getPosition(loop);
|
||||
vset.add(new IrisPosition(tipv.toBlockVector()));
|
||||
}
|
||||
|
||||
vset = getBallooned(vset, radius);
|
||||
if (!filled) {
|
||||
vset = getHollowed(vset);
|
||||
}
|
||||
|
||||
set(vset, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a 3d line
|
||||
* @param a the first point
|
||||
* @param b the second point
|
||||
* @param radius the radius
|
||||
* @param filled hollow or filled?
|
||||
* @param data the data
|
||||
* @param <T> the type of data to apply to the mantle
|
||||
*/
|
||||
public <T> void setLine(IrisPosition a, IrisPosition b, double radius, boolean filled, T data)
|
||||
{
|
||||
setLine(ImmutableList.of(a, b), radius, filled, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set lines for points
|
||||
* @param vectors the points
|
||||
* @param radius the radius
|
||||
* @param filled hollow or filled?
|
||||
* @param data the data to set
|
||||
* @param <T> the type of data to apply to the mantle
|
||||
*/
|
||||
public <T> void setLine(List<IrisPosition> vectors, double radius, boolean filled, T data) {
|
||||
Set<IrisPosition> vset = new KSet<>();
|
||||
|
||||
for (int i = 0; vectors.size() != 0 && i < vectors.size() - 1; i++) {
|
||||
IrisPosition pos1 = vectors.get(i);
|
||||
IrisPosition pos2 = vectors.get(i + 1);
|
||||
int x1 = pos1.getX();
|
||||
int y1 = pos1.getY();
|
||||
int z1 = pos1.getZ();
|
||||
int x2 = pos2.getX();
|
||||
int y2 = pos2.getY();
|
||||
int z2 = pos2.getZ();
|
||||
int tipx = x1;
|
||||
int tipy = y1;
|
||||
int tipz = z1;
|
||||
int dx = Math.abs(x2 - x1);
|
||||
int dy = Math.abs(y2 - y1);
|
||||
int dz = Math.abs(z2 - z1);
|
||||
|
||||
if (dx + dy + dz == 0) {
|
||||
vset.add(new IrisPosition(tipx, tipy, tipz));
|
||||
continue;
|
||||
}
|
||||
|
||||
int dMax = Math.max(Math.max(dx, dy), dz);
|
||||
if (dMax == dx) {
|
||||
for (int domstep = 0; domstep <= dx; domstep++) {
|
||||
tipx = x1 + domstep * (x2 - x1 > 0 ? 1 : -1);
|
||||
tipy = (int) Math.round(y1 + domstep * ((double) dy) / ((double) dx) * (y2 - y1 > 0 ? 1 : -1));
|
||||
tipz = (int) Math.round(z1 + domstep * ((double) dz) / ((double) dx) * (z2 - z1 > 0 ? 1 : -1));
|
||||
|
||||
vset.add(new IrisPosition(tipx, tipy, tipz));
|
||||
}
|
||||
} else if (dMax == dy) {
|
||||
for (int domstep = 0; domstep <= dy; domstep++) {
|
||||
tipy = y1 + domstep * (y2 - y1 > 0 ? 1 : -1);
|
||||
tipx = (int) Math.round(x1 + domstep * ((double) dx) / ((double) dy) * (x2 - x1 > 0 ? 1 : -1));
|
||||
tipz = (int) Math.round(z1 + domstep * ((double) dz) / ((double) dy) * (z2 - z1 > 0 ? 1 : -1));
|
||||
|
||||
vset.add(new IrisPosition(tipx, tipy, tipz));
|
||||
}
|
||||
} else /* if (dMax == dz) */ {
|
||||
for (int domstep = 0; domstep <= dz; domstep++) {
|
||||
tipz = z1 + domstep * (z2 - z1 > 0 ? 1 : -1);
|
||||
tipy = (int) Math.round(y1 + domstep * ((double) dy) / ((double) dz) * (y2 - y1 > 0 ? 1 : -1));
|
||||
tipx = (int) Math.round(x1 + domstep * ((double) dx) / ((double) dz) * (x2 - x1 > 0 ? 1 : -1));
|
||||
|
||||
vset.add(new IrisPosition(tipx, tipy, tipz));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vset = getBallooned(vset, radius);
|
||||
|
||||
if (!filled) {
|
||||
vset = getHollowed(vset);
|
||||
}
|
||||
|
||||
set(vset, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a cylinder in the mantle
|
||||
* @param cx the center x
|
||||
* @param cy the base y
|
||||
* @param cz the center z
|
||||
* @param data the data to set
|
||||
* @param radius the radius
|
||||
* @param height the height of the cyl
|
||||
* @param filled filled or not
|
||||
*/
|
||||
public <T> void setCylinder(int cx, int cy, int cz, T data, double radius, int height, boolean filled){
|
||||
setCylinder(cx, cy, cz, data, radius, radius, height, filled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a cylinder in the mantle
|
||||
* @param cx the center x
|
||||
* @param cy the base y
|
||||
* @param cz the center z
|
||||
* @param data the data to set
|
||||
* @param radiusX the x radius
|
||||
* @param radiusZ the z radius
|
||||
* @param height the height of this cyl
|
||||
* @param filled filled or hollow?
|
||||
*/
|
||||
public <T> void setCylinder(int cx, int cy, int cz, T data, double radiusX, double radiusZ, int height, boolean filled) {
|
||||
int affected = 0;
|
||||
radiusX += 0.5;
|
||||
radiusZ += 0.5;
|
||||
|
||||
if (height == 0) {
|
||||
return;
|
||||
} else if (height < 0) {
|
||||
height = -height;
|
||||
cy = cy - height;
|
||||
}
|
||||
|
||||
if (cy < 0) {
|
||||
cy = 0;
|
||||
} else if (cy + height - 1 > worldHeight) {
|
||||
height = worldHeight - cy + 1;
|
||||
}
|
||||
|
||||
final double invRadiusX = 1 / radiusX;
|
||||
final double invRadiusZ = 1 / radiusZ;
|
||||
final int ceilRadiusX = (int) Math.ceil(radiusX);
|
||||
final int ceilRadiusZ = (int) Math.ceil(radiusZ);
|
||||
double nextXn = 0;
|
||||
|
||||
forX: for (int x = 0; x <= ceilRadiusX; ++x) {
|
||||
final double xn = nextXn;
|
||||
nextXn = (x + 1) * invRadiusX;
|
||||
double nextZn = 0;
|
||||
for (int z = 0; z <= ceilRadiusZ; ++z) {
|
||||
final double zn = nextZn;
|
||||
nextZn = (z + 1) * invRadiusZ;
|
||||
double distanceSq = lengthSq(xn, zn);
|
||||
|
||||
if (distanceSq > 1) {
|
||||
if (z == 0) {
|
||||
break forX;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (!filled) {
|
||||
if (lengthSq(nextXn, zn) <= 1 && lengthSq(xn, nextZn) <= 1) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
for (int y = 0; y < height; ++y) {
|
||||
set(cx + x, cy + y, cz + z, data);
|
||||
set(cx + -x, cy + y, cz + z, data);
|
||||
set(cx + x, cy + y, cz + -z, data);
|
||||
set(cx + -x, cy + y, cz + -z, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public <T> void set(IrisPosition pos, T data)
|
||||
{
|
||||
set(pos.getX(), pos.getY(), pos.getZ(), data);
|
||||
}
|
||||
|
||||
public <T> void set(List<IrisPosition> positions, T data)
|
||||
{
|
||||
for(IrisPosition i : positions)
|
||||
{
|
||||
set(i, data);
|
||||
}
|
||||
}
|
||||
|
||||
public <T> void set(Set<IrisPosition> positions, T data)
|
||||
{
|
||||
for(IrisPosition i : positions)
|
||||
{
|
||||
set(i, data);
|
||||
}
|
||||
}
|
||||
|
||||
private static Set<IrisPosition> getBallooned(Set<IrisPosition> vset, double radius) {
|
||||
Set<IrisPosition> returnset = new HashSet<>();
|
||||
int ceilrad = (int) Math.ceil(radius);
|
||||
|
||||
for (IrisPosition v : vset) {
|
||||
int tipx = v.getX();
|
||||
int tipy = v.getY();
|
||||
int tipz = v.getZ();
|
||||
|
||||
for (int loopx = tipx - ceilrad; loopx <= tipx + ceilrad; loopx++) {
|
||||
for (int loopy = tipy - ceilrad; loopy <= tipy + ceilrad; loopy++) {
|
||||
for (int loopz = tipz - ceilrad; loopz <= tipz + ceilrad; loopz++) {
|
||||
if (hypot(loopx - tipx, loopy - tipy, loopz - tipz) <= radius) {
|
||||
returnset.add(new IrisPosition(loopx, loopy, loopz));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnset;
|
||||
}
|
||||
|
||||
private static Set<IrisPosition> getHollowed(Set<IrisPosition> vset) {
|
||||
Set<IrisPosition> returnset = new KSet<>();
|
||||
for (IrisPosition v : vset) {
|
||||
double x = v.getX();
|
||||
double y = v.getY();
|
||||
double z = v.getZ();
|
||||
if (!(vset.contains(new IrisPosition(x + 1, y, z))
|
||||
&& vset.contains(new IrisPosition(x - 1, y, z))
|
||||
&& vset.contains(new IrisPosition(x, y + 1, z))
|
||||
&& vset.contains(new IrisPosition(x, y - 1, z))
|
||||
&& vset.contains(new IrisPosition(x, y, z + 1))
|
||||
&& vset.contains(new IrisPosition(x, y, z - 1)))) {
|
||||
returnset.add(v);
|
||||
}
|
||||
}
|
||||
return returnset;
|
||||
}
|
||||
|
||||
private static double hypot(double... pars) {
|
||||
double sum = 0;
|
||||
for (double d : pars) {
|
||||
sum += Math.pow(d, 2);
|
||||
}
|
||||
return Math.sqrt(sum);
|
||||
}
|
||||
|
||||
private static double lengthSq(double x, double y, double z) {
|
||||
return (x * x) + (y * y) + (z * z);
|
||||
}
|
||||
|
||||
private static double lengthSq(double x, double z) {
|
||||
return (x * x) + (z * z);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user