mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-04-05 07:16:22 +00:00
Repackage utils
This commit is contained in:
56
src/main/java/com/volmit/iris/util/math/AlignedPoint.java
Normal file
56
src/main/java/com/volmit/iris/util/math/AlignedPoint.java
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.math;
|
||||
|
||||
public class AlignedPoint {
|
||||
private double x;
|
||||
private double y;
|
||||
private double z;
|
||||
|
||||
public AlignedPoint(double x, double y, double z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
public double getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public void setX(double x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public double getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public void setY(double y) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public double getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
public void setZ(double z) {
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
}
|
||||
101
src/main/java/com/volmit/iris/util/math/Average.java
Normal file
101
src/main/java/com/volmit/iris/util/math/Average.java
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.math;
|
||||
|
||||
import com.volmit.iris.util.DoubleArrayUtils;
|
||||
|
||||
/**
|
||||
* Provides an incredibly fast averaging object. It swaps values from a sum
|
||||
* using an array. Averages do not use any form of looping. An average of 10,000
|
||||
* entries is the same speed as an average with 5 entries.
|
||||
*
|
||||
* @author cyberpwn
|
||||
*/
|
||||
public class Average {
|
||||
protected final double[] values;
|
||||
private double average;
|
||||
private double lastSum;
|
||||
private boolean dirty;
|
||||
protected int cursor;
|
||||
private boolean brandNew;
|
||||
|
||||
/**
|
||||
* Create an average holder
|
||||
*
|
||||
* @param size the size of entries to keep
|
||||
*/
|
||||
public Average(int size) {
|
||||
values = new double[size];
|
||||
DoubleArrayUtils.fill(values, 0);
|
||||
brandNew = true;
|
||||
average = 0;
|
||||
cursor = 0;
|
||||
lastSum = 0;
|
||||
dirty = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Put a value into the average (rolls over if full)
|
||||
*
|
||||
* @param i the value
|
||||
*/
|
||||
public void put(double i) {
|
||||
|
||||
dirty = true;
|
||||
|
||||
if (brandNew) {
|
||||
DoubleArrayUtils.fill(values, i);
|
||||
lastSum = size() * i;
|
||||
brandNew = false;
|
||||
return;
|
||||
}
|
||||
|
||||
double current = values[cursor];
|
||||
lastSum = (lastSum - current) + i;
|
||||
values[cursor] = i;
|
||||
cursor = cursor + 1 < size() ? cursor + 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current average
|
||||
*
|
||||
* @return the average
|
||||
*/
|
||||
public double getAverage() {
|
||||
if (dirty) {
|
||||
calculateAverage();
|
||||
return getAverage();
|
||||
}
|
||||
|
||||
return average;
|
||||
}
|
||||
|
||||
private void calculateAverage() {
|
||||
average = lastSum / (double) size();
|
||||
dirty = false;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return values.length;
|
||||
}
|
||||
|
||||
public boolean isDirty() {
|
||||
return dirty;
|
||||
}
|
||||
}
|
||||
91
src/main/java/com/volmit/iris/util/math/AxisAlignedBB.java
Normal file
91
src/main/java/com/volmit/iris/util/math/AxisAlignedBB.java
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.math;
|
||||
|
||||
import com.volmit.iris.engine.object.IrisPosition;
|
||||
import com.volmit.iris.util.Cuboid;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.util.BlockVector;
|
||||
|
||||
public class AxisAlignedBB {
|
||||
private final double xa;
|
||||
private final double xb;
|
||||
private final double ya;
|
||||
private final double yb;
|
||||
private final double za;
|
||||
private final double zb;
|
||||
|
||||
public AxisAlignedBB(double xa, double xb, double ya, double yb, double za, double zb) {
|
||||
this.xa = xa;
|
||||
this.xb = xb;
|
||||
this.ya = ya;
|
||||
this.yb = yb;
|
||||
this.za = za;
|
||||
this.zb = zb;
|
||||
}
|
||||
|
||||
public AxisAlignedBB shifted(IrisPosition p) {
|
||||
return shifted(p.getX(), p.getY(), p.getZ());
|
||||
}
|
||||
|
||||
public AxisAlignedBB shifted(double x, double y, double z) {
|
||||
return new AxisAlignedBB(min().add(new IrisPosition((int) x, (int) y, (int) z)), max().add(new IrisPosition((int) x, (int) y, (int) z)));
|
||||
}
|
||||
|
||||
public AxisAlignedBB(AlignedPoint a, AlignedPoint b) {
|
||||
this(a.getX(), b.getX(), a.getY(), b.getY(), a.getZ(), b.getZ());
|
||||
}
|
||||
|
||||
public AxisAlignedBB(IrisPosition a, IrisPosition b) {
|
||||
this(a.getX(), b.getX(), a.getY(), b.getY(), a.getZ(), b.getZ());
|
||||
}
|
||||
|
||||
public boolean contains(AlignedPoint p) {
|
||||
return p.getX() >= xa && p.getX() <= xb && p.getY() >= ya && p.getZ() <= yb && p.getZ() >= za && p.getZ() <= zb;
|
||||
}
|
||||
|
||||
public boolean contains(IrisPosition p) {
|
||||
return p.getX() >= xa && p.getX() <= xb && p.getY() >= ya && p.getZ() <= yb && p.getZ() >= za && p.getZ() <= zb;
|
||||
}
|
||||
|
||||
public boolean intersects(AxisAlignedBB s) {
|
||||
return this.xb >= s.xa && this.yb >= s.ya && this.zb >= s.za && s.xb >= this.xa && s.yb >= this.ya && s.zb >= this.za;
|
||||
}
|
||||
|
||||
public IrisPosition max() {
|
||||
return new IrisPosition((int) xb, (int) yb, (int) zb);
|
||||
}
|
||||
|
||||
|
||||
public BlockVector maxbv() {
|
||||
return new BlockVector((int) xb, (int) yb, (int) zb);
|
||||
}
|
||||
|
||||
public IrisPosition min() {
|
||||
return new IrisPosition((int) xa, (int) ya, (int) za);
|
||||
}
|
||||
|
||||
public BlockVector minbv() {
|
||||
return new BlockVector((int) xa, (int) ya, (int) za);
|
||||
}
|
||||
|
||||
public Cuboid toCuboid(World world) {
|
||||
return new Cuboid(min().toLocation(world), max().toLocation(world));
|
||||
}
|
||||
}
|
||||
91
src/main/java/com/volmit/iris/util/math/BlockPosition.java
Normal file
91
src/main/java/com/volmit/iris/util/math/BlockPosition.java
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.math;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@Data
|
||||
public class BlockPosition {
|
||||
private int x;
|
||||
private int y;
|
||||
private int z;
|
||||
|
||||
//Magic numbers
|
||||
private static final int m1 = 1 + MathHelper.f(MathHelper.c(30000000));
|
||||
private static final int m2 = 64 - (m1 * 2);
|
||||
private static final long m3 = m1 + m2;
|
||||
private static final long m4 = (1L << m1) - 1L;
|
||||
private static final long m5 = (1L << m2) - 1L;
|
||||
private static final long m6 = (1L << m1) - 1L;
|
||||
|
||||
|
||||
public BlockPosition(int x, int y, int z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(x, y, z);
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (o == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (o instanceof BlockPosition ot) {
|
||||
|
||||
return ot.x == x && ot.y == y && ot.z == z;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getChunkX() {
|
||||
return x >> 4;
|
||||
}
|
||||
|
||||
public int getChunkZ() {
|
||||
return z >> 4;
|
||||
}
|
||||
|
||||
public boolean is(int x, int z) {
|
||||
return this.x == x && this.z == z;
|
||||
}
|
||||
|
||||
public boolean is(int x, int y, int z) {
|
||||
return this.x == x && this.y == y && this.z == z;
|
||||
}
|
||||
|
||||
public long asLong() {
|
||||
return toLong(getX(), getY(), getZ());
|
||||
}
|
||||
|
||||
public static long toLong(int x, int y, int z) {
|
||||
long var3 = 0L;
|
||||
var3 |= (x & m4) << m3;
|
||||
var3 |= (y & m5);
|
||||
var3 |= (z & m6) << m2;
|
||||
return var3;
|
||||
}
|
||||
}
|
||||
60
src/main/java/com/volmit/iris/util/math/CDou.java
Normal file
60
src/main/java/com/volmit/iris/util/math/CDou.java
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.math;
|
||||
|
||||
@SuppressWarnings("ALL")
|
||||
public class CDou {
|
||||
private double number;
|
||||
private final double max;
|
||||
|
||||
public CDou(double max) {
|
||||
number = 0;
|
||||
this.max = max;
|
||||
}
|
||||
|
||||
public CDou set(double n) {
|
||||
number = n;
|
||||
circ();
|
||||
return this;
|
||||
}
|
||||
|
||||
public CDou add(double a) {
|
||||
number += a;
|
||||
circ();
|
||||
return this;
|
||||
}
|
||||
|
||||
public CDou sub(double a) {
|
||||
number -= a;
|
||||
circ();
|
||||
return this;
|
||||
}
|
||||
|
||||
public double get() {
|
||||
return number;
|
||||
}
|
||||
|
||||
public void circ() {
|
||||
if (number < 0) {
|
||||
number = max - (Math.abs(number) > max ? max : Math.abs(number));
|
||||
}
|
||||
|
||||
number = number % (max);
|
||||
}
|
||||
}
|
||||
69
src/main/java/com/volmit/iris/util/math/ChunkPosition.java
Normal file
69
src/main/java/com/volmit/iris/util/math/ChunkPosition.java
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util;
|
||||
|
||||
public class ChunkPosition {
|
||||
private int x;
|
||||
private int z;
|
||||
|
||||
public ChunkPosition(int x, int z) {
|
||||
this.x = x;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public void setX(int x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public int getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
public void setZ(int z) {
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + x;
|
||||
result = prime * result + z;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof ChunkPosition other)) {
|
||||
return false;
|
||||
}
|
||||
return x == other.x && z == other.z;
|
||||
}
|
||||
|
||||
public double distance(ChunkPosition center) {
|
||||
return Math.pow(center.getX() - x, 2) + Math.pow(center.getZ() - z, 2);
|
||||
}
|
||||
}
|
||||
35
src/main/java/com/volmit/iris/util/math/DOP.java
Normal file
35
src/main/java/com/volmit/iris/util/math/DOP.java
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util;
|
||||
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public abstract class DOP {
|
||||
private final String type;
|
||||
|
||||
public DOP(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public abstract Vector op(Vector v);
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
383
src/main/java/com/volmit/iris/util/math/Direction.java
Normal file
383
src/main/java/com/volmit/iris/util/math/Direction.java
Normal file
@@ -0,0 +1,383 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.math;
|
||||
|
||||
import com.volmit.iris.util.Cuboid.CuboidDirection;
|
||||
import com.volmit.iris.util.DOP;
|
||||
import com.volmit.iris.util.GBiset;
|
||||
import com.volmit.iris.util.KList;
|
||||
import com.volmit.iris.util.KMap;
|
||||
import org.bukkit.Axis;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Directions
|
||||
*
|
||||
* @author cyberpwn
|
||||
*/
|
||||
public enum Direction {
|
||||
U(0, 1, 0, CuboidDirection.Up),
|
||||
D(0, -1, 0, CuboidDirection.Down),
|
||||
N(0, 0, -1, CuboidDirection.North),
|
||||
S(0, 0, 1, CuboidDirection.South),
|
||||
E(1, 0, 0, CuboidDirection.East),
|
||||
W(-1, 0, 0, CuboidDirection.West);
|
||||
|
||||
private static KMap<GBiset<Direction, Direction>, DOP> permute = null;
|
||||
|
||||
private final int x;
|
||||
private final int y;
|
||||
private final int z;
|
||||
private final CuboidDirection f;
|
||||
|
||||
public static Direction getDirection(BlockFace f) {
|
||||
return switch (f) {
|
||||
case DOWN -> D;
|
||||
case EAST, EAST_SOUTH_EAST, EAST_NORTH_EAST -> E;
|
||||
case NORTH, NORTH_WEST, NORTH_NORTH_WEST, NORTH_NORTH_EAST, NORTH_EAST -> N;
|
||||
case SELF, UP -> U;
|
||||
case SOUTH, SOUTH_WEST, SOUTH_SOUTH_WEST, SOUTH_SOUTH_EAST, SOUTH_EAST -> S;
|
||||
case WEST, WEST_SOUTH_WEST, WEST_NORTH_WEST -> W;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return switch (this) {
|
||||
case D -> "Down";
|
||||
case E -> "East";
|
||||
case N -> "North";
|
||||
case S -> "South";
|
||||
case U -> "Up";
|
||||
case W -> "West";
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
public boolean isVertical() {
|
||||
return equals(D) || equals(U);
|
||||
}
|
||||
|
||||
public static Direction closest(Vector v) {
|
||||
double m = Double.MAX_VALUE;
|
||||
Direction s = null;
|
||||
|
||||
for (Direction i : values()) {
|
||||
Vector x = i.toVector();
|
||||
double g = x.dot(v);
|
||||
|
||||
if (g < m) {
|
||||
m = g;
|
||||
s = i;
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
public static Direction closest(Vector v, Direction... d) {
|
||||
double m = Double.MAX_VALUE;
|
||||
Direction s = null;
|
||||
|
||||
for (Direction i : d) {
|
||||
Vector x = i.toVector();
|
||||
double g = x.distance(v);
|
||||
|
||||
if (g < m) {
|
||||
m = g;
|
||||
s = i;
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
public static Direction closest(Vector v, KList<Direction> d) {
|
||||
double m = Double.MAX_VALUE;
|
||||
Direction s = null;
|
||||
|
||||
for (Direction i : d) {
|
||||
Vector x = i.toVector();
|
||||
double g = x.distance(v);
|
||||
|
||||
if (g < m) {
|
||||
m = g;
|
||||
s = i;
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
public Vector toVector() {
|
||||
return new Vector(x, y, z);
|
||||
}
|
||||
|
||||
public boolean isCrooked(Direction to) {
|
||||
if (equals(to.reverse())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !equals(to);
|
||||
}
|
||||
|
||||
Direction(int x, int y, int z, CuboidDirection f) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.f = f;
|
||||
}
|
||||
|
||||
public Vector angle(Vector initial, Direction d) {
|
||||
calculatePermutations();
|
||||
|
||||
for (Map.Entry<GBiset<Direction, Direction>, DOP> entry : permute.entrySet()) {
|
||||
GBiset<Direction, Direction> i = entry.getKey();
|
||||
if (i.getA().equals(this) && i.getB().equals(d)) {
|
||||
return entry.getValue().op(initial);
|
||||
}
|
||||
}
|
||||
|
||||
return initial;
|
||||
}
|
||||
|
||||
public Direction reverse() {
|
||||
switch (this) {
|
||||
case D:
|
||||
return U;
|
||||
case E:
|
||||
return W;
|
||||
case N:
|
||||
return S;
|
||||
case S:
|
||||
return N;
|
||||
case U:
|
||||
return D;
|
||||
case W:
|
||||
return E;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public int x() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public int y() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public int z() {
|
||||
return z;
|
||||
}
|
||||
|
||||
public CuboidDirection f() {
|
||||
return f;
|
||||
}
|
||||
|
||||
public static KList<Direction> news() {
|
||||
return new KList<Direction>().add(N, E, W, S);
|
||||
}
|
||||
|
||||
public static Direction getDirection(Vector v) {
|
||||
Vector k = VectorMath.triNormalize(v.clone().normalize());
|
||||
|
||||
for (Direction i : udnews()) {
|
||||
if (i.x == k.getBlockX() && i.y == k.getBlockY() && i.z == k.getBlockZ()) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return Direction.N;
|
||||
}
|
||||
|
||||
public static KList<Direction> udnews() {
|
||||
return new KList<Direction>().add(U, D, N, E, W, S);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the directional value from the given byte from common directional blocks
|
||||
* (MUST BE BETWEEN 0 and 5 INCLUSIVE)
|
||||
*
|
||||
* @param b the byte
|
||||
* @return the direction or null if the byte is outside of the inclusive range
|
||||
* 0-5
|
||||
*/
|
||||
public static Direction fromByte(byte b) {
|
||||
if (b > 5 || b < 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (b == 0) {
|
||||
return D;
|
||||
} else if (b == 1) {
|
||||
return U;
|
||||
} else if (b == 2) {
|
||||
return N;
|
||||
} else if (b == 3) {
|
||||
return S;
|
||||
} else if (b == 4) {
|
||||
return W;
|
||||
} else {
|
||||
return E;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the byte value represented in some directional blocks
|
||||
*
|
||||
* @return the byte value
|
||||
*/
|
||||
public byte byteValue() {
|
||||
switch (this) {
|
||||
case D:
|
||||
return 0;
|
||||
case E:
|
||||
return 5;
|
||||
case N:
|
||||
return 2;
|
||||
case S:
|
||||
return 3;
|
||||
case U:
|
||||
return 1;
|
||||
case W:
|
||||
return 4;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static void calculatePermutations() {
|
||||
if (permute != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
permute = new KMap<>();
|
||||
|
||||
for (Direction i : udnews()) {
|
||||
for (Direction j : udnews()) {
|
||||
GBiset<Direction, Direction> b = new GBiset<>(i, j);
|
||||
|
||||
if (i.equals(j)) {
|
||||
permute.put(b, new DOP("DIRECT") {
|
||||
@Override
|
||||
public Vector op(Vector v) {
|
||||
return v;
|
||||
}
|
||||
});
|
||||
} else if (i.reverse().equals(j)) {
|
||||
if (i.isVertical()) {
|
||||
permute.put(b, new DOP("R180CCZ") {
|
||||
@Override
|
||||
public Vector op(Vector v) {
|
||||
return VectorMath.rotate90CCZ(VectorMath.rotate90CCZ(v));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
permute.put(b, new DOP("R180CCY") {
|
||||
@Override
|
||||
public Vector op(Vector v) {
|
||||
return VectorMath.rotate90CCY(VectorMath.rotate90CCY(v));
|
||||
}
|
||||
});
|
||||
}
|
||||
} else if (getDirection(VectorMath.rotate90CX(i.toVector())).equals(j)) {
|
||||
permute.put(b, new DOP("R90CX") {
|
||||
@Override
|
||||
public Vector op(Vector v) {
|
||||
return VectorMath.rotate90CX(v);
|
||||
}
|
||||
});
|
||||
} else if (getDirection(VectorMath.rotate90CCX(i.toVector())).equals(j)) {
|
||||
permute.put(b, new DOP("R90CCX") {
|
||||
@Override
|
||||
public Vector op(Vector v) {
|
||||
return VectorMath.rotate90CCX(v);
|
||||
}
|
||||
});
|
||||
} else if (getDirection(VectorMath.rotate90CY(i.toVector())).equals(j)) {
|
||||
permute.put(b, new DOP("R90CY") {
|
||||
@Override
|
||||
public Vector op(Vector v) {
|
||||
return VectorMath.rotate90CY(v);
|
||||
}
|
||||
});
|
||||
} else if (getDirection(VectorMath.rotate90CCY(i.toVector())).equals(j)) {
|
||||
permute.put(b, new DOP("R90CCY") {
|
||||
@Override
|
||||
public Vector op(Vector v) {
|
||||
return VectorMath.rotate90CCY(v);
|
||||
}
|
||||
});
|
||||
} else if (getDirection(VectorMath.rotate90CZ(i.toVector())).equals(j)) {
|
||||
permute.put(b, new DOP("R90CZ") {
|
||||
@Override
|
||||
public Vector op(Vector v) {
|
||||
return VectorMath.rotate90CZ(v);
|
||||
}
|
||||
});
|
||||
} else if (getDirection(VectorMath.rotate90CCZ(i.toVector())).equals(j)) {
|
||||
permute.put(b, new DOP("R90CCZ") {
|
||||
@Override
|
||||
public Vector op(Vector v) {
|
||||
return VectorMath.rotate90CCZ(v);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
permute.put(b, new DOP("FAIL") {
|
||||
@Override
|
||||
public Vector op(Vector v) {
|
||||
return v;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public BlockFace getFace() {
|
||||
return switch (this) {
|
||||
case D -> BlockFace.DOWN;
|
||||
case E -> BlockFace.EAST;
|
||||
case N -> BlockFace.NORTH;
|
||||
case S -> BlockFace.SOUTH;
|
||||
case U -> BlockFace.UP;
|
||||
case W -> BlockFace.WEST;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
public Axis getAxis() {
|
||||
return switch (this) {
|
||||
case D, U -> Axis.Y;
|
||||
case E, W -> Axis.X;
|
||||
case N, S -> Axis.Z;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
50
src/main/java/com/volmit/iris/util/math/FinalInteger.java
Normal file
50
src/main/java/com/volmit/iris/util/math/FinalInteger.java
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util;
|
||||
|
||||
import com.volmit.iris.util.scheduling.Wrapper;
|
||||
|
||||
/**
|
||||
* Represents a number that can be finalized and be changed
|
||||
*
|
||||
* @author cyberpwn
|
||||
*/
|
||||
public class FinalInteger extends Wrapper<Integer> {
|
||||
public FinalInteger(Integer t) {
|
||||
super(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add to this value
|
||||
*
|
||||
* @param i the number to add to this value (value = value + i)
|
||||
*/
|
||||
public void add(int i) {
|
||||
set(get() + i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract from this value
|
||||
*
|
||||
* @param i the number to subtract from this value (value = value - i)
|
||||
*/
|
||||
public void sub(int i) {
|
||||
set(get() - i);
|
||||
}
|
||||
}
|
||||
454
src/main/java/com/volmit/iris/util/math/IrisMathHelper.java
Normal file
454
src/main/java/com/volmit/iris/util/math/IrisMathHelper.java
Normal file
@@ -0,0 +1,454 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
import java.util.function.IntPredicate;
|
||||
|
||||
public class IrisMathHelper {
|
||||
public static final float a;
|
||||
private static final Random c;
|
||||
private static final int[] d;
|
||||
private static final double e;
|
||||
private static final double[] f;
|
||||
private static final double[] g;
|
||||
|
||||
public static float c(final float var0) {
|
||||
return (float) Math.sqrt(var0);
|
||||
}
|
||||
|
||||
public static float sqrt(final double var0) {
|
||||
return (float) Math.sqrt(var0);
|
||||
}
|
||||
|
||||
public static int d(final float var0) {
|
||||
final int var = (int) var0;
|
||||
return (var0 < var) ? (var - 1) : var;
|
||||
}
|
||||
|
||||
public static int floor(final double var0) {
|
||||
final int var = (int) var0;
|
||||
return (var0 < var) ? (var - 1) : var;
|
||||
}
|
||||
|
||||
public static long d(final double var0) {
|
||||
final long var = (long) var0;
|
||||
return (var0 < var) ? (var - 1L) : var;
|
||||
}
|
||||
|
||||
public static float e(final float var0) {
|
||||
return Math.abs(var0);
|
||||
}
|
||||
|
||||
public static int a(final int var0) {
|
||||
return Math.abs(var0);
|
||||
}
|
||||
|
||||
public static int f(final float var0) {
|
||||
final int var = (int) var0;
|
||||
return (var0 > var) ? (var + 1) : var;
|
||||
}
|
||||
|
||||
public static int f(final double var0) {
|
||||
final int var = (int) var0;
|
||||
return (var0 > var) ? (var + 1) : var;
|
||||
}
|
||||
|
||||
public static int clamp(final int var0, final int var1, final int var2) {
|
||||
if (var0 < var1) {
|
||||
return var1;
|
||||
}
|
||||
return Math.min(var0, var2);
|
||||
}
|
||||
|
||||
public static float a(final float var0, final float var1, final float var2) {
|
||||
if (var0 < var1) {
|
||||
return var1;
|
||||
}
|
||||
return Math.min(var0, var2);
|
||||
}
|
||||
|
||||
public static double a(final double var0, final double var2, final double var4) {
|
||||
if (var0 < var2) {
|
||||
return var2;
|
||||
}
|
||||
return Math.min(var0, var4);
|
||||
}
|
||||
|
||||
public static double b(final double var0, final double var2, final double var4) {
|
||||
if (var4 < 0.0) {
|
||||
return var0;
|
||||
}
|
||||
if (var4 > 1.0) {
|
||||
return var2;
|
||||
}
|
||||
return d(var4, var0, var2);
|
||||
}
|
||||
|
||||
public static double a(double var0, double var2) {
|
||||
if (var0 < 0.0) {
|
||||
var0 = -var0;
|
||||
}
|
||||
if (var2 < 0.0) {
|
||||
var2 = -var2;
|
||||
}
|
||||
return Math.max(var0, var2);
|
||||
}
|
||||
|
||||
public static int a(final int var0, final int var1) {
|
||||
return Math.floorDiv(var0, var1);
|
||||
}
|
||||
|
||||
public static int nextInt(final Random var0, final int var1, final int var2) {
|
||||
if (var1 >= var2) {
|
||||
return var1;
|
||||
}
|
||||
return var0.nextInt(var2 - var1 + 1) + var1;
|
||||
}
|
||||
|
||||
public static float a(final Random var0, final float var1, final float var2) {
|
||||
if (var1 >= var2) {
|
||||
return var1;
|
||||
}
|
||||
return var0.nextFloat() * (var2 - var1) + var1;
|
||||
}
|
||||
|
||||
public static double a(final Random var0, final double var1, final double var3) {
|
||||
if (var1 >= var3) {
|
||||
return var1;
|
||||
}
|
||||
return var0.nextDouble() * (var3 - var1) + var1;
|
||||
}
|
||||
|
||||
public static double a(final long[] var0) {
|
||||
long var = 0L;
|
||||
for (final long var2 : var0) {
|
||||
var += var2;
|
||||
}
|
||||
return var / (double) var0.length;
|
||||
}
|
||||
|
||||
public static boolean b(final double var0, final double var2) {
|
||||
return Math.abs(var2 - var0) < 9.999999747378752E-6;
|
||||
}
|
||||
|
||||
public static int b(final int var0, final int var1) {
|
||||
return Math.floorMod(var0, var1);
|
||||
}
|
||||
|
||||
public static float g(final float var0) {
|
||||
float var = var0 % 360.0f;
|
||||
if (var >= 180.0f) {
|
||||
var -= 360.0f;
|
||||
}
|
||||
if (var < -180.0f) {
|
||||
var += 360.0f;
|
||||
}
|
||||
return var;
|
||||
}
|
||||
|
||||
public static double g(final double var0) {
|
||||
double var = var0 % 360.0;
|
||||
if (var >= 180.0) {
|
||||
var -= 360.0;
|
||||
}
|
||||
if (var < -180.0) {
|
||||
var += 360.0;
|
||||
}
|
||||
return var;
|
||||
}
|
||||
|
||||
public static float c(final float var0, final float var1) {
|
||||
return g(var1 - var0);
|
||||
}
|
||||
|
||||
public static float d(final float var0, final float var1) {
|
||||
return e(c(var0, var1));
|
||||
}
|
||||
|
||||
public static float b(final float var0, final float var1, final float var2) {
|
||||
final float var3 = c(var0, var1);
|
||||
final float var4 = a(var3, -var2, var2);
|
||||
return var1 - var4;
|
||||
}
|
||||
|
||||
public static float c(final float var0, final float var1, float var2) {
|
||||
var2 = e(var2);
|
||||
if (var0 < var1) {
|
||||
return a(var0 + var2, var0, var1);
|
||||
}
|
||||
return a(var0 - var2, var1, var0);
|
||||
}
|
||||
|
||||
public static float d(final float var0, final float var1, final float var2) {
|
||||
final float var3 = c(var0, var1);
|
||||
return c(var0, var0 + var3, var2);
|
||||
}
|
||||
|
||||
public static int c(final int var0) {
|
||||
int var = var0 - 1;
|
||||
var |= var >> 1;
|
||||
var |= var >> 2;
|
||||
var |= var >> 4;
|
||||
var |= var >> 8;
|
||||
var |= var >> 16;
|
||||
return var + 1;
|
||||
}
|
||||
|
||||
public static boolean d(final int var0) {
|
||||
return var0 != 0 && (var0 & var0 - 1) == 0x0;
|
||||
}
|
||||
|
||||
public static int e(int var0) {
|
||||
var0 = (d(var0) ? var0 : c(var0));
|
||||
return IrisMathHelper.d[(int) (var0 * 125613361L >> 27) & 0x1F];
|
||||
}
|
||||
|
||||
public static int f(final int var0) {
|
||||
return e(var0) - (d(var0) ? 0 : 1);
|
||||
}
|
||||
|
||||
public static int c(final int var0, int var1) {
|
||||
if (var1 == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (var0 == 0) {
|
||||
return var1;
|
||||
}
|
||||
if (var0 < 0) {
|
||||
var1 *= -1;
|
||||
}
|
||||
final int var2 = var0 % var1;
|
||||
if (var2 == 0) {
|
||||
return var0;
|
||||
}
|
||||
return var0 + var1 - var2;
|
||||
}
|
||||
|
||||
public static float h(final float var0) {
|
||||
return var0 - d(var0);
|
||||
}
|
||||
|
||||
public static double h(final double var0) {
|
||||
return var0 - d(var0);
|
||||
}
|
||||
|
||||
public static long c(final int var0, final int var1, final int var2) {
|
||||
long var3 = (long) (var0 * 3129871L) ^ var2 * 116129781L ^ (long) var1;
|
||||
var3 = var3 * var3 * 42317861L + var3 * 11L;
|
||||
return var3 >> 16;
|
||||
}
|
||||
|
||||
public static UUID a(final Random var0) {
|
||||
final long var = (var0.nextLong() & 0xFFFFFFFFFFFF0FFFL) | 0x4000L;
|
||||
final long var2 = (var0.nextLong() & 0x3FFFFFFFFFFFFFFFL) | Long.MIN_VALUE;
|
||||
return new UUID(var, var2);
|
||||
}
|
||||
|
||||
public static UUID a() {
|
||||
return a(IrisMathHelper.c);
|
||||
}
|
||||
|
||||
public static double c(final double var0, final double var2, final double var4) {
|
||||
return (var0 - var2) / (var4 - var2);
|
||||
}
|
||||
|
||||
public static double d(double var0, double var2) {
|
||||
final double var3 = var2 * var2 + var0 * var0;
|
||||
if (Double.isNaN(var3)) {
|
||||
return Double.NaN;
|
||||
}
|
||||
final boolean var4 = var0 < 0.0;
|
||||
if (var4) {
|
||||
var0 = -var0;
|
||||
}
|
||||
final boolean var5 = var2 < 0.0;
|
||||
if (var5) {
|
||||
var2 = -var2;
|
||||
}
|
||||
final boolean var6 = var0 > var2;
|
||||
if (var6) {
|
||||
final double var7 = var2;
|
||||
var2 = var0;
|
||||
var0 = var7;
|
||||
}
|
||||
final double var7 = i(var3);
|
||||
var2 *= var7;
|
||||
var0 *= var7;
|
||||
final double var8 = IrisMathHelper.e + var0;
|
||||
final int var9 = (int) Double.doubleToRawLongBits(var8);
|
||||
final double var10 = IrisMathHelper.f[var9];
|
||||
final double var11 = IrisMathHelper.g[var9];
|
||||
final double var12 = var8 - IrisMathHelper.e;
|
||||
final double var13 = var0 * var11 - var2 * var12;
|
||||
final double var14 = (6.0 + var13 * var13) * var13 * 0.16666666666666666;
|
||||
double var15 = var10 + var14;
|
||||
if (var6) {
|
||||
var15 = 1.5707963267948966 - var15;
|
||||
}
|
||||
if (var5) {
|
||||
var15 = 3.141592653589793 - var15;
|
||||
}
|
||||
if (var4) {
|
||||
var15 = -var15;
|
||||
}
|
||||
return var15;
|
||||
}
|
||||
|
||||
public static double i(double var0) {
|
||||
final double var = 0.5 * var0;
|
||||
long var2 = Double.doubleToRawLongBits(var0);
|
||||
var2 = 6910469410427058090L - (var2 >> 1);
|
||||
var0 = Double.longBitsToDouble(var2);
|
||||
var0 *= 1.5 - var * var0 * var0;
|
||||
return var0;
|
||||
}
|
||||
|
||||
public static int f(final float var0, final float var1, final float var2) {
|
||||
final int var3 = (int) (var0 * 6.0f) % 6;
|
||||
final float var4 = var0 * 6.0f - var3;
|
||||
final float var5 = var2 * (1.0f - var1);
|
||||
final float var6 = var2 * (1.0f - var4 * var1);
|
||||
final float var7 = var2 * (1.0f - (1.0f - var4) * var1);
|
||||
float var8 = 0.0f;
|
||||
float var9 = 0.0f;
|
||||
float var10 = 0.0f;
|
||||
switch (var3) {
|
||||
case 0 -> {
|
||||
var8 = var2;
|
||||
var9 = var7;
|
||||
var10 = var5;
|
||||
}
|
||||
case 1 -> {
|
||||
var8 = var6;
|
||||
var9 = var2;
|
||||
var10 = var5;
|
||||
}
|
||||
case 2 -> {
|
||||
var8 = var5;
|
||||
var9 = var2;
|
||||
var10 = var7;
|
||||
}
|
||||
case 3 -> {
|
||||
var8 = var5;
|
||||
var9 = var6;
|
||||
var10 = var2;
|
||||
}
|
||||
case 4 -> {
|
||||
var8 = var7;
|
||||
var9 = var5;
|
||||
var10 = var2;
|
||||
}
|
||||
case 5 -> {
|
||||
var8 = var2;
|
||||
var9 = var5;
|
||||
var10 = var6;
|
||||
}
|
||||
default -> {
|
||||
throw new RuntimeException("Something went wrong when converting from HSV to RGB. Input was " + var0 + ", " + var1 + ", " + var2);
|
||||
}
|
||||
}
|
||||
final int var11 = clamp((int) (var8 * 255.0f), 0, 255);
|
||||
final int var12 = clamp((int) (var9 * 255.0f), 0, 255);
|
||||
final int var13 = clamp((int) (var10 * 255.0f), 0, 255);
|
||||
return var11 << 16 | var12 << 8 | var13;
|
||||
}
|
||||
|
||||
public static int g(int var0) {
|
||||
var0 ^= var0 >>> 16;
|
||||
var0 *= -2048144789;
|
||||
var0 ^= var0 >>> 13;
|
||||
var0 *= -1028477387;
|
||||
var0 ^= var0 >>> 16;
|
||||
return var0;
|
||||
}
|
||||
|
||||
public static int a(int var0, final int var1, final IntPredicate var2) {
|
||||
int var3 = var1 - var0;
|
||||
while (var3 > 0) {
|
||||
final int var4 = var3 / 2;
|
||||
final int var5 = var0 + var4;
|
||||
if (var2.test(var5)) {
|
||||
var3 = var4;
|
||||
} else {
|
||||
var0 = var5 + 1;
|
||||
var3 -= var4 + 1;
|
||||
}
|
||||
}
|
||||
return var0;
|
||||
}
|
||||
|
||||
public static float g(final float var0, final float var1, final float var2) {
|
||||
return var1 + var0 * (var2 - var1);
|
||||
}
|
||||
|
||||
public static double d(final double var0, final double var2, final double var4) {
|
||||
return var2 + var0 * (var4 - var2);
|
||||
}
|
||||
|
||||
public static double a(final double var0, final double var2, final double var4, final double var6, final double var8, final double var10) {
|
||||
return d(var2, d(var0, var4, var6), d(var0, var8, var10));
|
||||
}
|
||||
|
||||
public static double a(final double var0, final double var2, final double var4, final double var6, final double var8, final double var10, final double var12, final double var14, final double var16, final double var18, final double var20) {
|
||||
return d(var4, a(var0, var2, var6, var8, var10, var12), a(var0, var2, var14, var16, var18, var20));
|
||||
}
|
||||
|
||||
public static double j(final double var0) {
|
||||
return var0 * var0 * var0 * (var0 * (var0 * 6.0 - 15.0) + 10.0);
|
||||
}
|
||||
|
||||
public static int k(final double var0) {
|
||||
if (var0 == 0.0) {
|
||||
return 0;
|
||||
}
|
||||
return (var0 > 0.0) ? 1 : -1;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static float j(final float var0, final float var1, final float var2) {
|
||||
float var3;
|
||||
for (var3 = var1 - var0; var3 < -180.0f; var3 += 360.0f) {
|
||||
}
|
||||
while (var3 >= 180.0f) {
|
||||
var3 -= 360.0f;
|
||||
}
|
||||
return var0 + var2 * var3;
|
||||
}
|
||||
|
||||
public static float k(final float var0) {
|
||||
return var0 * var0;
|
||||
}
|
||||
|
||||
static {
|
||||
a = c(2.0f);
|
||||
c = new Random();
|
||||
d = new int[]{0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9};
|
||||
e = Double.longBitsToDouble(4805340802404319232L);
|
||||
f = new double[257];
|
||||
g = new double[257];
|
||||
for (int var2 = 0; var2 < 257; ++var2) {
|
||||
final double var3 = var2 / 256.0;
|
||||
final double var4 = Math.asin(var3);
|
||||
IrisMathHelper.g[var2] = Math.cos(var4);
|
||||
IrisMathHelper.f[var2] = var4;
|
||||
}
|
||||
}
|
||||
}
|
||||
372
src/main/java/com/volmit/iris/util/math/M.java
Normal file
372
src/main/java/com/volmit/iris/util/math/M.java
Normal file
@@ -0,0 +1,372 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.math;
|
||||
|
||||
import javax.script.ScriptEngine;
|
||||
import javax.script.ScriptEngineManager;
|
||||
import javax.script.ScriptException;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
/**
|
||||
* Math
|
||||
*
|
||||
* @author cyberpwn
|
||||
*/
|
||||
public class M {
|
||||
private static final int precision = 128;
|
||||
private static final int modulus = 360 * precision;
|
||||
private static final float[] sin = new float[modulus];
|
||||
public static int tick = 0;
|
||||
|
||||
/**
|
||||
* Scales B by an external range change so that <br/>
|
||||
* <br/>
|
||||
* BMIN < B < BMAX <br/>
|
||||
* AMIN < RESULT < AMAX <br/>
|
||||
* <br/>
|
||||
* So Given rangeScale(0, 20, 0, 10, 5) -> 10 <br/>
|
||||
* 0 < 5 < 10 <br/>
|
||||
* 0 < ? < 20 <br/>
|
||||
* <br/>
|
||||
* would return 10
|
||||
*
|
||||
* @param amin the resulting minimum
|
||||
* @param amax the resulting maximum
|
||||
* @param bmin the initial minimum
|
||||
* @param bmax the initial maximum
|
||||
* @param b the initial value
|
||||
* @return the resulting value
|
||||
*/
|
||||
public static double rangeScale(double amin, double amax, double bmin, double bmax, double b) {
|
||||
return amin + ((amax - amin) * ((b - bmin) / (bmax - bmin)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the percent (inverse lerp) from "from" to "to" where "at".
|
||||
* <p>
|
||||
* If from = 0 and to = 100 and at = 25 then it would return 0.25
|
||||
*
|
||||
* @param from the from
|
||||
* @param to the to
|
||||
* @param at the at
|
||||
* @return the percent
|
||||
*/
|
||||
public static double lerpInverse(double from, double to, double at) {
|
||||
return M.rangeScale(0, 1, from, to, at);
|
||||
}
|
||||
|
||||
/**
|
||||
* Linear interpolation from a to b where f is the percent across
|
||||
*
|
||||
* @param a the first pos (0)
|
||||
* @param b the second pos (1)
|
||||
* @param f the percent
|
||||
* @return the value
|
||||
*/
|
||||
public static double lerp(double a, double b, double f) {
|
||||
return a + (f * (b - a));
|
||||
}
|
||||
|
||||
/**
|
||||
* Bilinear interpolation
|
||||
*
|
||||
* @param a the first point (0, 0)
|
||||
* @param b the second point (1, 0)
|
||||
* @param c the third point (0, 1)
|
||||
* @param d the fourth point (1, 1)
|
||||
* @return the bilerped value
|
||||
*/
|
||||
public static double bilerp(double a, double b, double c, double d, double x, double y) {
|
||||
return lerp(lerp(a, b, x), lerp(c, d, x), y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Trilinear interpolation
|
||||
*
|
||||
* @param a the first point (0, 0, 0)
|
||||
* @param b the second point (1, 0, 0)
|
||||
* @param c the third point (0, 0, 1)
|
||||
* @param d the fourth point (1, 0, 1)
|
||||
* @param e the fifth point (0, 1, 0)
|
||||
* @param f the sixth point (1, 1, 0)
|
||||
* @param g the seventh point (0, 1, 1)
|
||||
* @param h the eighth point (1, 1, 1)
|
||||
* @param x the x
|
||||
* @param y the y
|
||||
* @param z the z
|
||||
* @return the trilerped value
|
||||
*/
|
||||
public static double trilerp(double a, double b, double c, double d, double e, double f, double g, double h, double x, double y, double z) {
|
||||
return lerp(bilerp(a, b, c, d, x, y), bilerp(e, f, g, h, x, y), z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clip a value
|
||||
*
|
||||
* @param value the value
|
||||
* @param min the min
|
||||
* @param max the max
|
||||
* @return the clipped value
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends Number> T clip(T value, T min, T max) {
|
||||
return (T) Double.valueOf(Math.min(max.doubleValue(), Math.max(min.doubleValue(), value.doubleValue())));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get true or false based on random percent
|
||||
*
|
||||
* @param d between 0 and 1
|
||||
* @return true if true
|
||||
*/
|
||||
public static boolean r(Double d) {
|
||||
//noinspection ReplaceNullCheck
|
||||
if (d == null) {
|
||||
return Math.random() < 0.5;
|
||||
}
|
||||
|
||||
return Math.random() < d;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ticks per second from a time in nanoseconds, the rad can be used for
|
||||
* multiple ticks
|
||||
*
|
||||
* @param ns the time in nanoseconds
|
||||
* @param rad the radius of the time
|
||||
* @return the ticks per second in double form
|
||||
*/
|
||||
public static double tps(long ns, int rad) {
|
||||
return (20.0 * (ns / 50000000.0)) / rad;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of ticks from a time in nanoseconds
|
||||
*
|
||||
* @param ns the nanoseconds
|
||||
* @return the amount of ticks
|
||||
*/
|
||||
public static double ticksFromNS(long ns) {
|
||||
return (ns / 50000000.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random int from to (inclusive)
|
||||
*
|
||||
* @param f the from
|
||||
* @param t the to
|
||||
* @return the value
|
||||
*/
|
||||
public static int irand(int f, int t) {
|
||||
return f + (int) (Math.random() * ((t - f) + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random float from to (inclusive)
|
||||
*
|
||||
* @param f the from
|
||||
* @param t the to
|
||||
* @return the value
|
||||
*/
|
||||
public static float frand(float f, float t) {
|
||||
return f + (float) (Math.random() * ((t - f) + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random double from to (inclusive)
|
||||
*
|
||||
* @param f the from
|
||||
* @param t the to
|
||||
* @return the value
|
||||
*/
|
||||
public static double drand(double f, double t) {
|
||||
return f + (Math.random() * ((t - f) + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get system Nanoseconds
|
||||
*
|
||||
* @return nanoseconds (current)
|
||||
*/
|
||||
public static long ns() {
|
||||
return System.nanoTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current millisecond time
|
||||
*
|
||||
* @return milliseconds
|
||||
*/
|
||||
public static long ms() {
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fast sin function
|
||||
*
|
||||
* @param a the number
|
||||
* @return the sin
|
||||
*/
|
||||
public static float sin(float a) {
|
||||
return sinLookup((int) (a * precision + 0.5f));
|
||||
}
|
||||
|
||||
/**
|
||||
* Fast cos function
|
||||
*
|
||||
* @param a the number
|
||||
* @return the cos
|
||||
*/
|
||||
public static float cos(float a) {
|
||||
return sinLookup((int) ((a + 90f) * precision + 0.5f));
|
||||
}
|
||||
|
||||
/**
|
||||
* Fast tan function
|
||||
*
|
||||
* @param a the number
|
||||
* @return the tan
|
||||
*/
|
||||
public static float tan(float a) {
|
||||
float c = cos(a);
|
||||
return sin(a) / (c == 0 ? 0.0000001f : c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Biggest number
|
||||
*
|
||||
* @return the biggest one
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends Number> T max(T... doubles) {
|
||||
double max = Double.MIN_VALUE;
|
||||
|
||||
for (T i : doubles) {
|
||||
if (i.doubleValue() > max) {
|
||||
max = i.doubleValue();
|
||||
}
|
||||
}
|
||||
|
||||
return (T) Double.valueOf(max);
|
||||
}
|
||||
|
||||
/**
|
||||
* Smallest number
|
||||
*
|
||||
* @param doubles the numbers
|
||||
* @return the smallest one
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends Number> T min(T... doubles) {
|
||||
double min = Double.MAX_VALUE;
|
||||
|
||||
for (T i : doubles) {
|
||||
if (i.doubleValue() < min) {
|
||||
min = i.doubleValue();
|
||||
}
|
||||
}
|
||||
|
||||
return (T) Double.valueOf(min);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates an expression using javascript engine and returns the double
|
||||
* result. This can take variable parameters, so you need to define them.
|
||||
* Parameters are defined as $[0-9]. For example evaluate("4$0/$1", 1, 2); This
|
||||
* makes the expression (4x1)/2 == 2. Keep note that you must use 0-9, you
|
||||
* cannot skip, or start at a number other than 0.
|
||||
*
|
||||
* @param expression the expression with variables
|
||||
* @param args the arguments/variables
|
||||
* @return the resulting double value
|
||||
* @throws ScriptException ... gg
|
||||
* @throws IndexOutOfBoundsException learn to count
|
||||
*/
|
||||
public static double evaluate(String expression, Double... args) throws ScriptException, IndexOutOfBoundsException {
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
String current = "$" + i;
|
||||
|
||||
if (expression.contains(current)) {
|
||||
expression = expression.replaceAll(Matcher.quoteReplacement(current), args[i] + "");
|
||||
}
|
||||
}
|
||||
|
||||
return evaluate(expression);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates an expression using javascript engine and returns the double
|
||||
*
|
||||
* @param expression the mathimatical expression
|
||||
* @return the double result
|
||||
* @throws ScriptException ... gg
|
||||
*/
|
||||
public static double evaluate(String expression) throws ScriptException {
|
||||
ScriptEngineManager mgr = new ScriptEngineManager();
|
||||
ScriptEngine scriptEngine = mgr.getEngineByName("JavaScript");
|
||||
|
||||
return Double.parseDouble(scriptEngine.eval(expression).toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* is the number "is" within from-to
|
||||
*
|
||||
* @param from the lower end
|
||||
* @param to the upper end
|
||||
* @param is the check
|
||||
* @return true if its within
|
||||
*/
|
||||
public static boolean within(int from, int to, int is) {
|
||||
return is >= from && is <= to;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the amount of days past since the epoch time (1970 jan 1 utc)
|
||||
*
|
||||
* @return the epoch days
|
||||
*/
|
||||
public static long epochDays() {
|
||||
return epochDays(M.ms());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the amount of days past since the epoch time (1970 jan 1 utc)
|
||||
*
|
||||
* @param ms the time in milliseconds
|
||||
* @return the epoch days
|
||||
*/
|
||||
private static long epochDays(long ms) {
|
||||
return ms / 1000 / 60 / 60 / 24;
|
||||
}
|
||||
|
||||
static {
|
||||
for (int i = 0; i < sin.length; i++) {
|
||||
sin[i] = (float) Math.sin((i * Math.PI) / (precision * 180));
|
||||
}
|
||||
}
|
||||
|
||||
private static float sinLookup(int a) {
|
||||
return a >= 0 ? sin[a % (modulus)] : -sin[-a % (modulus)];
|
||||
}
|
||||
|
||||
public static boolean interval(int tickInterval) {
|
||||
return tick % (tickInterval <= 0 ? 1 : tickInterval) == 0;
|
||||
}
|
||||
|
||||
}
|
||||
479
src/main/java/com/volmit/iris/util/math/MathHelper.java
Normal file
479
src/main/java/com/volmit/iris/util/math/MathHelper.java
Normal file
@@ -0,0 +1,479 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.math;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.IntPredicate;
|
||||
|
||||
public class MathHelper {
|
||||
public static final float a = MathHelper.c(2.0f);
|
||||
private static final float[] b = (float[]) a((Object) new float[65536], var0 ->
|
||||
{
|
||||
for (int var1 = 0; var1 < ((float[]) var0).length; ++var1) {
|
||||
((float[]) var0)[var1] = (float) Math.sin((double) var1 * 3.141592653589793 * 2.0 / 65536.0);
|
||||
}
|
||||
});
|
||||
|
||||
public static <T> T a(T var0, Consumer<T> var1) {
|
||||
var1.accept(var0);
|
||||
return var0;
|
||||
}
|
||||
|
||||
private static final Random c = new Random();
|
||||
private static final int[] d = new int[]{0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9};
|
||||
private static final double e = Double.longBitsToDouble(4805340802404319232L);
|
||||
private static final double[] f = new double[257];
|
||||
private static final double[] g = new double[257];
|
||||
|
||||
public static float sin(float var0) {
|
||||
return b[(int) (var0 * 10430.378f) & 65535];
|
||||
}
|
||||
|
||||
public static float cos(float var0) {
|
||||
return b[(int) (var0 * 10430.378f + 16384.0f) & 65535];
|
||||
}
|
||||
|
||||
public static float c(float var0) {
|
||||
return (float) Math.sqrt(var0);
|
||||
}
|
||||
|
||||
public static float sqrt(double var0) {
|
||||
return (float) Math.sqrt(var0);
|
||||
}
|
||||
|
||||
public static int d(float var0) {
|
||||
int var1 = (int) var0;
|
||||
return var0 < (float) var1 ? var1 - 1 : var1;
|
||||
}
|
||||
|
||||
public static int floor(double var0) {
|
||||
int var2 = (int) var0;
|
||||
return var0 < (double) var2 ? var2 - 1 : var2;
|
||||
}
|
||||
|
||||
public static long d(double var0) {
|
||||
long var2 = (long) var0;
|
||||
return var0 < (double) var2 ? var2 - 1L : var2;
|
||||
}
|
||||
|
||||
public static float e(float var0) {
|
||||
return Math.abs(var0);
|
||||
}
|
||||
|
||||
public static int a(int var0) {
|
||||
return Math.abs(var0);
|
||||
}
|
||||
|
||||
public static int f(float var0) {
|
||||
int var1 = (int) var0;
|
||||
return var0 > (float) var1 ? var1 + 1 : var1;
|
||||
}
|
||||
|
||||
public static int f(double var0) {
|
||||
int var2 = (int) var0;
|
||||
return var0 > (double) var2 ? var2 + 1 : var2;
|
||||
}
|
||||
|
||||
public static int clamp(int var0, int var1, int var2) {
|
||||
if (var0 < var1) {
|
||||
return var1;
|
||||
}
|
||||
return Math.min(var0, var2);
|
||||
}
|
||||
|
||||
public static float a(float var0, float var1, float var2) {
|
||||
if (var0 < var1) {
|
||||
return var1;
|
||||
}
|
||||
return Math.min(var0, var2);
|
||||
}
|
||||
|
||||
public static double a(double var0, double var2, double var4) {
|
||||
if (var0 < var2) {
|
||||
return var2;
|
||||
}
|
||||
return Math.min(var0, var4);
|
||||
}
|
||||
|
||||
public static double b(double var0, double var2, double var4) {
|
||||
if (var4 < 0.0) {
|
||||
return var0;
|
||||
}
|
||||
if (var4 > 1.0) {
|
||||
return var2;
|
||||
}
|
||||
return MathHelper.d(var4, var0, var2);
|
||||
}
|
||||
|
||||
public static double a(double var0, double var2) {
|
||||
if (var0 < 0.0) {
|
||||
var0 = -var0;
|
||||
}
|
||||
if (var2 < 0.0) {
|
||||
var2 = -var2;
|
||||
}
|
||||
return Math.max(var0, var2);
|
||||
}
|
||||
|
||||
public static int a(int var0, int var1) {
|
||||
return Math.floorDiv(var0, var1);
|
||||
}
|
||||
|
||||
public static int nextInt(Random var0, int var1, int var2) {
|
||||
if (var1 >= var2) {
|
||||
return var1;
|
||||
}
|
||||
return var0.nextInt(var2 - var1 + 1) + var1;
|
||||
}
|
||||
|
||||
public static float a(Random var0, float var1, float var2) {
|
||||
if (var1 >= var2) {
|
||||
return var1;
|
||||
}
|
||||
return var0.nextFloat() * (var2 - var1) + var1;
|
||||
}
|
||||
|
||||
public static double a(Random var0, double var1, double var3) {
|
||||
if (var1 >= var3) {
|
||||
return var1;
|
||||
}
|
||||
return var0.nextDouble() * (var3 - var1) + var1;
|
||||
}
|
||||
|
||||
public static double a(long[] var0) {
|
||||
long var1 = 0L;
|
||||
for (long var6 : var0) {
|
||||
var1 += var6;
|
||||
}
|
||||
return (double) var1 / (double) var0.length;
|
||||
}
|
||||
|
||||
public static boolean b(double var0, double var2) {
|
||||
return Math.abs(var2 - var0) < 9.999999747378752E-6;
|
||||
}
|
||||
|
||||
public static int b(int var0, int var1) {
|
||||
return Math.floorMod(var0, var1);
|
||||
}
|
||||
|
||||
public static float g(float var0) {
|
||||
float var1 = var0 % 360.0f;
|
||||
if (var1 >= 180.0f) {
|
||||
var1 -= 360.0f;
|
||||
}
|
||||
if (var1 < -180.0f) {
|
||||
var1 += 360.0f;
|
||||
}
|
||||
return var1;
|
||||
}
|
||||
|
||||
public static double g(double var0) {
|
||||
double var2 = var0 % 360.0;
|
||||
if (var2 >= 180.0) {
|
||||
var2 -= 360.0;
|
||||
}
|
||||
if (var2 < -180.0) {
|
||||
var2 += 360.0;
|
||||
}
|
||||
return var2;
|
||||
}
|
||||
|
||||
public static float c(float var0, float var1) {
|
||||
return MathHelper.g(var1 - var0);
|
||||
}
|
||||
|
||||
public static float d(float var0, float var1) {
|
||||
return MathHelper.e(MathHelper.c(var0, var1));
|
||||
}
|
||||
|
||||
public static float b(float var0, float var1, float var2) {
|
||||
float var3 = MathHelper.c(var0, var1);
|
||||
float var4 = MathHelper.a(var3, -var2, var2);
|
||||
return var1 - var4;
|
||||
}
|
||||
|
||||
public static float c(float var0, float var1, float var2) {
|
||||
var2 = MathHelper.e(var2);
|
||||
if (var0 < var1) {
|
||||
return MathHelper.a(var0 + var2, var0, var1);
|
||||
}
|
||||
return MathHelper.a(var0 - var2, var1, var0);
|
||||
}
|
||||
|
||||
public static float d(float var0, float var1, float var2) {
|
||||
float var3 = MathHelper.c(var0, var1);
|
||||
return MathHelper.c(var0, var0 + var3, var2);
|
||||
}
|
||||
|
||||
public static int c(int var0) {
|
||||
int var1 = var0 - 1;
|
||||
var1 |= var1 >> 1;
|
||||
var1 |= var1 >> 2;
|
||||
var1 |= var1 >> 4;
|
||||
var1 |= var1 >> 8;
|
||||
var1 |= var1 >> 16;
|
||||
return var1 + 1;
|
||||
}
|
||||
|
||||
public static boolean d(int var0) {
|
||||
return var0 != 0 && (var0 & var0 - 1) == 0;
|
||||
}
|
||||
|
||||
public static int e(int var0) {
|
||||
var0 = MathHelper.d(var0) ? var0 : MathHelper.c(var0);
|
||||
return d[(int) ((long) var0 * 125613361L >> 27) & 31];
|
||||
}
|
||||
|
||||
public static int f(int var0) {
|
||||
return MathHelper.e(var0) - (MathHelper.d(var0) ? 0 : 1);
|
||||
}
|
||||
|
||||
public static int c(int var0, int var1) {
|
||||
int var2;
|
||||
if (var1 == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (var0 == 0) {
|
||||
return var1;
|
||||
}
|
||||
if (var0 < 0) {
|
||||
var1 *= -1;
|
||||
}
|
||||
if ((var2 = var0 % var1) == 0) {
|
||||
return var0;
|
||||
}
|
||||
return var0 + var1 - var2;
|
||||
}
|
||||
|
||||
public static float h(float var0) {
|
||||
return var0 - (float) MathHelper.d(var0);
|
||||
}
|
||||
|
||||
public static double h(double var0) {
|
||||
return var0 - (double) MathHelper.d(var0);
|
||||
}
|
||||
|
||||
public static long a(BlockPosition var0) {
|
||||
return c(var0.getX(), var0.getY(), var0.getZ());
|
||||
}
|
||||
|
||||
public static long c(int var0, int var1, int var2) {
|
||||
long var3 = (var0 * 3129871L) ^ (long) var2 * 116129781L ^ (long) var1;
|
||||
var3 = var3 * var3 * 42317861L + var3 * 11L;
|
||||
return var3 >> 16;
|
||||
}
|
||||
|
||||
public static UUID a(Random var0) {
|
||||
long var1 = var0.nextLong() & -61441L | 16384L;
|
||||
long var3 = var0.nextLong() & 0x3FFFFFFFFFFFFFFFL | Long.MIN_VALUE;
|
||||
return new UUID(var1, var3);
|
||||
}
|
||||
|
||||
public static UUID a() {
|
||||
return MathHelper.a(c);
|
||||
}
|
||||
|
||||
public static double c(double var0, double var2, double var4) {
|
||||
return (var0 - var2) / (var4 - var2);
|
||||
}
|
||||
|
||||
public static double d(double var0, double var2) {
|
||||
double var9;
|
||||
boolean var6;
|
||||
boolean var7;
|
||||
boolean var8;
|
||||
double var4 = var2 * var2 + var0 * var0;
|
||||
if (Double.isNaN(var4)) {
|
||||
return Double.NaN;
|
||||
}
|
||||
@SuppressWarnings("unused")
|
||||
boolean bl = var6 = var0 < 0.0;
|
||||
if (var6) {
|
||||
var0 = -var0;
|
||||
}
|
||||
@SuppressWarnings("unused")
|
||||
boolean bl2 = var7 = var2 < 0.0;
|
||||
if (var7) {
|
||||
var2 = -var2;
|
||||
}
|
||||
@SuppressWarnings("unused")
|
||||
boolean bl3 = var8 = var0 > var2;
|
||||
if (var8) {
|
||||
var9 = var2;
|
||||
var2 = var0;
|
||||
var0 = var9;
|
||||
}
|
||||
var9 = MathHelper.i(var4);
|
||||
double var11 = e + (var0 *= var9);
|
||||
int var13 = (int) Double.doubleToRawLongBits(var11);
|
||||
double var14 = f[var13];
|
||||
double var16 = g[var13];
|
||||
double var18 = var11 - e;
|
||||
double var20 = var0 * var16 - (var2 *= var9) * var18;
|
||||
double var22 = (6.0 + var20 * var20) * var20 * 0.16666666666666666;
|
||||
double var24 = var14 + var22;
|
||||
if (var8) {
|
||||
var24 = 1.5707963267948966 - var24;
|
||||
}
|
||||
if (var7) {
|
||||
var24 = 3.141592653589793 - var24;
|
||||
}
|
||||
if (var6) {
|
||||
var24 = -var24;
|
||||
}
|
||||
return var24;
|
||||
}
|
||||
|
||||
public static double i(double var0) {
|
||||
double var2 = 0.5 * var0;
|
||||
long var4 = Double.doubleToRawLongBits(var0);
|
||||
var4 = 6910469410427058090L - (var4 >> 1);
|
||||
var0 = Double.longBitsToDouble(var4);
|
||||
var0 *= 1.5 - var2 * var0 * var0;
|
||||
return var0;
|
||||
}
|
||||
|
||||
public static int f(float var0, float var1, float var2) {
|
||||
float var9;
|
||||
float var8;
|
||||
float var10;
|
||||
int var3 = (int) (var0 * 6.0f) % 6;
|
||||
float var4 = var0 * 6.0f - (float) var3;
|
||||
float var5 = var2 * (1.0f - var1);
|
||||
float var6 = var2 * (1.0f - var4 * var1);
|
||||
float var7 = var2 * (1.0f - (1.0f - var4) * var1);
|
||||
switch (var3) {
|
||||
case 0 -> {
|
||||
var8 = var2;
|
||||
var9 = var7;
|
||||
var10 = var5;
|
||||
}
|
||||
case 1 -> {
|
||||
var8 = var6;
|
||||
var9 = var2;
|
||||
var10 = var5;
|
||||
}
|
||||
case 2 -> {
|
||||
var8 = var5;
|
||||
var9 = var2;
|
||||
var10 = var7;
|
||||
}
|
||||
case 3 -> {
|
||||
var8 = var5;
|
||||
var9 = var6;
|
||||
var10 = var2;
|
||||
}
|
||||
case 4 -> {
|
||||
var8 = var7;
|
||||
var9 = var5;
|
||||
var10 = var2;
|
||||
}
|
||||
case 5 -> {
|
||||
var8 = var2;
|
||||
var9 = var5;
|
||||
var10 = var6;
|
||||
}
|
||||
default -> {
|
||||
throw new RuntimeException("Something went wrong when converting from HSV to RGB. Input was " + var0 + ", " + var1 + ", " + var2);
|
||||
}
|
||||
}
|
||||
int var11 = MathHelper.clamp((int) (var8 * 255.0f), 0, 255);
|
||||
int var12 = MathHelper.clamp((int) (var9 * 255.0f), 0, 255);
|
||||
int var13 = MathHelper.clamp((int) (var10 * 255.0f), 0, 255);
|
||||
return var11 << 16 | var12 << 8 | var13;
|
||||
}
|
||||
|
||||
public static int g(int var0) {
|
||||
var0 ^= var0 >>> 16;
|
||||
var0 *= -2048144789;
|
||||
var0 ^= var0 >>> 13;
|
||||
var0 *= -1028477387;
|
||||
var0 ^= var0 >>> 16;
|
||||
return var0;
|
||||
}
|
||||
|
||||
public static int a(int var0, int var1, IntPredicate var2) {
|
||||
int var3 = var1 - var0;
|
||||
while (var3 > 0) {
|
||||
int var4 = var3 / 2;
|
||||
int var5 = var0 + var4;
|
||||
if (var2.test(var5)) {
|
||||
var3 = var4;
|
||||
continue;
|
||||
}
|
||||
var0 = var5 + 1;
|
||||
var3 -= var4 + 1;
|
||||
}
|
||||
return var0;
|
||||
}
|
||||
|
||||
public static float g(float var0, float var1, float var2) {
|
||||
return var1 + var0 * (var2 - var1);
|
||||
}
|
||||
|
||||
public static double d(double var0, double var2, double var4) {
|
||||
return var2 + var0 * (var4 - var2);
|
||||
}
|
||||
|
||||
public static double a(double var0, double var2, double var4, double var6, double var8, double var10) {
|
||||
return MathHelper.d(var2, MathHelper.d(var0, var4, var6), MathHelper.d(var0, var8, var10));
|
||||
}
|
||||
|
||||
public static double a(double var0, double var2, double var4, double var6, double var8, double var10, double var12, double var14, double var16, double var18, double var20) {
|
||||
return MathHelper.d(var4, MathHelper.a(var0, var2, var6, var8, var10, var12), MathHelper.a(var0, var2, var14, var16, var18, var20));
|
||||
}
|
||||
|
||||
public static double j(double var0) {
|
||||
return var0 * var0 * var0 * (var0 * (var0 * 6.0 - 15.0) + 10.0);
|
||||
}
|
||||
|
||||
public static int k(double var0) {
|
||||
if (var0 == 0.0) {
|
||||
return 0;
|
||||
}
|
||||
return var0 > 0.0 ? 1 : -1;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static float j(float var0, float var1, float var2) {
|
||||
float var3;
|
||||
for (var3 = var1 - var0; var3 < -180.0f; var3 += 360.0f) {
|
||||
}
|
||||
while (var3 >= 180.0f) {
|
||||
var3 -= 360.0f;
|
||||
}
|
||||
return var0 + var2 * var3;
|
||||
}
|
||||
|
||||
public static float k(float var0) {
|
||||
return var0 * var0;
|
||||
}
|
||||
|
||||
static {
|
||||
for (int var02 = 0; var02 < 257; ++var02) {
|
||||
// TODO: WARNING HEIGHT
|
||||
double var1 = (double) var02 / 256.0;
|
||||
double var3 = Math.asin(var1);
|
||||
MathHelper.g[var02] = Math.cos(var3);
|
||||
MathHelper.f[var02] = var3;
|
||||
}
|
||||
}
|
||||
}
|
||||
179
src/main/java/com/volmit/iris/util/math/Point3d.java
Normal file
179
src/main/java/com/volmit/iris/util/math/Point3d.java
Normal file
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.math;
|
||||
|
||||
/**
|
||||
* A 3 element point that is represented by double precision floating point
|
||||
* x,y,z coordinates.
|
||||
*/
|
||||
public class Point3d extends Tuple3d implements java.io.Serializable {
|
||||
|
||||
// Compatible with 1.1
|
||||
static final long serialVersionUID = 5718062286069042927L;
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Point3d from the specified xyz coordinates.
|
||||
*
|
||||
* @param x the x coordinate
|
||||
* @param y the y coordinate
|
||||
* @param z the z coordinate
|
||||
*/
|
||||
public Point3d(double x, double y, double z) {
|
||||
super(x, y, z);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Point3d from the array of length 3.
|
||||
*
|
||||
* @param p the array of length 3 containing xyz in order
|
||||
*/
|
||||
public Point3d(double[] p) {
|
||||
super(p);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Point3d from the specified Point3d.
|
||||
*
|
||||
* @param p1 the Point3d containing the initialization x y z data
|
||||
*/
|
||||
public Point3d(Point3d p1) {
|
||||
super(p1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Point3d from the specified Point3f.
|
||||
*
|
||||
* @param p1 the Point3f containing the initialization x y z data
|
||||
*/
|
||||
public Point3d(Point3f p1) {
|
||||
super(p1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Point3d from the specified Tuple3f.
|
||||
*
|
||||
* @param t1 the Tuple3f containing the initialization x y z data
|
||||
*/
|
||||
public Point3d(Tuple3f t1) {
|
||||
super(t1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Point3d from the specified Tuple3d.
|
||||
*
|
||||
* @param t1 the Tuple3d containing the initialization x y z data
|
||||
*/
|
||||
public Point3d(Tuple3d t1) {
|
||||
super(t1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Point3d to (0,0,0).
|
||||
*/
|
||||
public Point3d() {
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the square of the distance between this point and point p1.
|
||||
*
|
||||
* @param p1 the other point
|
||||
* @return the square of the distance
|
||||
*/
|
||||
public final double distanceSquared(Point3d p1) {
|
||||
double dx, dy, dz;
|
||||
|
||||
dx = this.x - p1.x;
|
||||
dy = this.y - p1.y;
|
||||
dz = this.z - p1.z;
|
||||
return (dx * dx + dy * dy + dz * dz);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the distance between this point and point p1.
|
||||
*
|
||||
* @param p1 the other point
|
||||
* @return the distance
|
||||
*/
|
||||
public final double distance(Point3d p1) {
|
||||
double dx, dy, dz;
|
||||
|
||||
dx = this.x - p1.x;
|
||||
dy = this.y - p1.y;
|
||||
dz = this.z - p1.z;
|
||||
return Math.sqrt(dx * dx + dy * dy + dz * dz);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Computes the L-1 (Manhattan) distance between this point and
|
||||
* point p1. The L-1 distance is equal to:
|
||||
* abs(x1-x2) + abs(y1-y2) + abs(z1-z2).
|
||||
*
|
||||
* @param p1 the other point
|
||||
* @return the L-1 distance
|
||||
*/
|
||||
public final double distanceL1(Point3d p1) {
|
||||
return Math.abs(this.x - p1.x) + Math.abs(this.y - p1.y) +
|
||||
Math.abs(this.z - p1.z);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Computes the L-infinite distance between this point and
|
||||
* point p1. The L-infinite distance is equal to
|
||||
* MAX[abs(x1-x2), abs(y1-y2), abs(z1-z2)].
|
||||
*
|
||||
* @param p1 the other point
|
||||
* @return the L-infinite distance
|
||||
*/
|
||||
public final double distanceLinf(Point3d p1) {
|
||||
double tmp;
|
||||
tmp = Math.max(Math.abs(this.x - p1.x), Math.abs(this.y - p1.y));
|
||||
|
||||
return Math.max(tmp, Math.abs(this.z - p1.z));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Multiplies each of the x,y,z components of the Point4d parameter
|
||||
* by 1/w and places the projected values into this point.
|
||||
*
|
||||
* @param p1 the source Point4d, which is not modified
|
||||
*/
|
||||
public final void project(Point4d p1) {
|
||||
double oneOw;
|
||||
|
||||
oneOw = 1 / p1.w;
|
||||
x = p1.x * oneOw;
|
||||
y = p1.y * oneOw;
|
||||
z = p1.z * oneOw;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
180
src/main/java/com/volmit/iris/util/math/Point3f.java
Normal file
180
src/main/java/com/volmit/iris/util/math/Point3f.java
Normal file
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.math;
|
||||
|
||||
/**
|
||||
* A 3 element point that is represented by single precision floating point
|
||||
* x,y,z coordinates.
|
||||
*/
|
||||
public class Point3f extends Tuple3f implements java.io.Serializable {
|
||||
|
||||
|
||||
// Compatible with 1.1
|
||||
static final long serialVersionUID = -8689337816398030143L;
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Point3f from the specified xyz coordinates.
|
||||
*
|
||||
* @param x the x coordinate
|
||||
* @param y the y coordinate
|
||||
* @param z the z coordinate
|
||||
*/
|
||||
public Point3f(float x, float y, float z) {
|
||||
super(x, y, z);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Point3f from the array of length 3.
|
||||
*
|
||||
* @param p the array of length 3 containing xyz in order
|
||||
*/
|
||||
public Point3f(float[] p) {
|
||||
super(p);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Point3f from the specified Point3f.
|
||||
*
|
||||
* @param p1 the Point3f containing the initialization x y z data
|
||||
*/
|
||||
public Point3f(Point3f p1) {
|
||||
super(p1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Point3f from the specified Point3d.
|
||||
*
|
||||
* @param p1 the Point3d containing the initialization x y z data
|
||||
*/
|
||||
public Point3f(Point3d p1) {
|
||||
super(p1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Point3f from the specified Tuple3f.
|
||||
*
|
||||
* @param t1 the Tuple3f containing the initialization x y z data
|
||||
*/
|
||||
public Point3f(Tuple3f t1) {
|
||||
super(t1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Point3f from the specified Tuple3d.
|
||||
*
|
||||
* @param t1 the Tuple3d containing the initialization x y z data
|
||||
*/
|
||||
public Point3f(Tuple3d t1) {
|
||||
super(t1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Point3f to (0,0,0).
|
||||
*/
|
||||
public Point3f() {
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Computes the square of the distance between this point and
|
||||
* point p1.
|
||||
*
|
||||
* @param p1 the other point
|
||||
* @return the square of the distance
|
||||
*/
|
||||
public final float distanceSquared(Point3f p1) {
|
||||
float dx, dy, dz;
|
||||
|
||||
dx = this.x - p1.x;
|
||||
dy = this.y - p1.y;
|
||||
dz = this.z - p1.z;
|
||||
return dx * dx + dy * dy + dz * dz;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Computes the distance between this point and point p1.
|
||||
*
|
||||
* @param p1 the other point
|
||||
* @return the distance
|
||||
*/
|
||||
public final float distance(Point3f p1) {
|
||||
float dx, dy, dz;
|
||||
|
||||
dx = this.x - p1.x;
|
||||
dy = this.y - p1.y;
|
||||
dz = this.z - p1.z;
|
||||
return (float) Math.sqrt(dx * dx + dy * dy + dz * dz);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Computes the L-1 (Manhattan) distance between this point and
|
||||
* point p1. The L-1 distance is equal to:
|
||||
* abs(x1-x2) + abs(y1-y2) + abs(z1-z2).
|
||||
*
|
||||
* @param p1 the other point
|
||||
* @return the L-1 distance
|
||||
*/
|
||||
public final float distanceL1(Point3f p1) {
|
||||
return (Math.abs(this.x - p1.x) + Math.abs(this.y - p1.y) + Math.abs(this.z - p1.z));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Computes the L-infinite distance between this point and
|
||||
* point p1. The L-infinite distance is equal to
|
||||
* MAX[abs(x1-x2), abs(y1-y2), abs(z1-z2)].
|
||||
*
|
||||
* @param p1 the other point
|
||||
* @return the L-infinite distance
|
||||
*/
|
||||
public final float distanceLinf(Point3f p1) {
|
||||
float tmp;
|
||||
tmp = Math.max(Math.abs(this.x - p1.x), Math.abs(this.y - p1.y));
|
||||
return (Math.max(tmp, Math.abs(this.z - p1.z)));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Multiplies each of the x,y,z components of the Point4f parameter
|
||||
* by 1/w and places the projected values into this point.
|
||||
*
|
||||
* @param p1 the source Point4f, which is not modified
|
||||
*/
|
||||
public final void project(Point4f p1) {
|
||||
float oneOw;
|
||||
|
||||
oneOw = 1 / p1.w;
|
||||
x = p1.x * oneOw;
|
||||
y = p1.y * oneOw;
|
||||
z = p1.z * oneOw;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
214
src/main/java/com/volmit/iris/util/math/Point4d.java
Normal file
214
src/main/java/com/volmit/iris/util/math/Point4d.java
Normal file
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.math;
|
||||
|
||||
/**
|
||||
* A 4 element vector represented by double precision floating point
|
||||
* x,y,z,w coordinates.
|
||||
*/
|
||||
public class Point4d extends Tuple4d implements java.io.Serializable {
|
||||
|
||||
// Compatible with 1.1
|
||||
static final long serialVersionUID = 1733471895962736949L;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Point4d from the specified xyzw coordinates.
|
||||
*
|
||||
* @param x the x coordinate
|
||||
* @param y the y coordinate
|
||||
* @param z the z coordinate
|
||||
* @param w the w coordinate
|
||||
*/
|
||||
public Point4d(double x, double y, double z, double w) {
|
||||
super(x, y, z, w);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Point4d from the coordinates contained
|
||||
* in the array.
|
||||
*
|
||||
* @param p the array of length 4 containing xyzw in order
|
||||
*/
|
||||
public Point4d(double[] p) {
|
||||
super(p);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Point4d from the specified Point4d.
|
||||
*
|
||||
* @param p1 the Point4d containing the initialization x y z w data
|
||||
*/
|
||||
public Point4d(Point4d p1) {
|
||||
super(p1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Point4d from the specified Point4f.
|
||||
*
|
||||
* @param p1 the Point4f containing the initialization x y z w data
|
||||
*/
|
||||
public Point4d(Point4f p1) {
|
||||
super(p1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Point4d from the specified Tuple4f.
|
||||
*
|
||||
* @param t1 the Tuple4f containing the initialization x y z w data
|
||||
*/
|
||||
public Point4d(Tuple4f t1) {
|
||||
super(t1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Point4d from the specified Tuple4d.
|
||||
*
|
||||
* @param t1 the Tuple4d containing the initialization x y z w data
|
||||
*/
|
||||
public Point4d(Tuple4d t1) {
|
||||
super(t1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Point4d from the specified Tuple3d.
|
||||
* The x,y,z components of this point are set to the corresponding
|
||||
* components of tuple t1. The w component of this point
|
||||
* is set to 1.
|
||||
*
|
||||
* @param t1 the tuple to be copied
|
||||
* @since vecmath 1.2
|
||||
*/
|
||||
public Point4d(Tuple3d t1) {
|
||||
super(t1.x, t1.y, t1.z, 1.0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Point4d to (0,0,0,0).
|
||||
*/
|
||||
public Point4d() {
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the x,y,z components of this point to the corresponding
|
||||
* components of tuple t1. The w component of this point
|
||||
* is set to 1.
|
||||
*
|
||||
* @param t1 the tuple to be copied
|
||||
* @since vecmath 1.2
|
||||
*/
|
||||
public final void set(Tuple3d t1) {
|
||||
this.x = t1.x;
|
||||
this.y = t1.y;
|
||||
this.z = t1.z;
|
||||
this.w = 1.0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the square of the distance between this point and point p1.
|
||||
*
|
||||
* @param p1 the first point
|
||||
* @return the square of distance between this point and point p1
|
||||
*/
|
||||
public final double distanceSquared(Point4d p1) {
|
||||
double dx, dy, dz, dw;
|
||||
|
||||
dx = this.x - p1.x;
|
||||
dy = this.y - p1.y;
|
||||
dz = this.z - p1.z;
|
||||
dw = this.w - p1.w;
|
||||
return (dx * dx + dy * dy + dz * dz + dw * dw);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the distance between this point and point p1.
|
||||
*
|
||||
* @param p1 the first point
|
||||
* @return the distance between these this point and point p1.
|
||||
*/
|
||||
public final double distance(Point4d p1) {
|
||||
double dx, dy, dz, dw;
|
||||
|
||||
dx = this.x - p1.x;
|
||||
dy = this.y - p1.y;
|
||||
dz = this.z - p1.z;
|
||||
dw = this.w - p1.w;
|
||||
return Math.sqrt(dx * dx + dy * dy + dz * dz + dw * dw);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Computes the L-1 (Manhattan) distance between this point and
|
||||
* point p1. The L-1 distance is equal to:
|
||||
* abs(x1-x2) + abs(y1-y2) + abs(z1-z2) + abs(w1-w2).
|
||||
*
|
||||
* @param p1 the other point
|
||||
* @return the L-1 distance
|
||||
*/
|
||||
public final double distanceL1(Point4d p1) {
|
||||
return Math.abs(this.x - p1.x) + Math.abs(this.y - p1.y) +
|
||||
Math.abs(this.z - p1.z) + Math.abs(this.w - p1.w);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the L-infinite distance between this point and
|
||||
* point p1. The L-infinite distance is equal to
|
||||
* MAX[abs(x1-x2), abs(y1-y2), abs(z1-z2), abs(w1-w2)].
|
||||
*
|
||||
* @param p1 the other point
|
||||
* @return the L-infinite distance
|
||||
*/
|
||||
public final double distanceLinf(Point4d p1) {
|
||||
double t1, t2;
|
||||
t1 = Math.max(Math.abs(this.x - p1.x), Math.abs(this.y - p1.y));
|
||||
t2 = Math.max(Math.abs(this.z - p1.z), Math.abs(this.w - p1.w));
|
||||
|
||||
return Math.max(t1, t2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies each of the x,y,z components of the Point4d parameter
|
||||
* by 1/w, places the projected values into this point, and places
|
||||
* a 1 as the w parameter of this point.
|
||||
*
|
||||
* @param p1 the source Point4d, which is not modified
|
||||
*/
|
||||
public final void project(Point4d p1) {
|
||||
double oneOw;
|
||||
|
||||
oneOw = 1 / p1.w;
|
||||
x = p1.x * oneOw;
|
||||
y = p1.y * oneOw;
|
||||
z = p1.z * oneOw;
|
||||
w = 1.0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
214
src/main/java/com/volmit/iris/util/math/Point4f.java
Normal file
214
src/main/java/com/volmit/iris/util/math/Point4f.java
Normal file
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.math;
|
||||
|
||||
/**
|
||||
* A 4 element point represented by single precision floating point x,y,z,w
|
||||
* coordinates.
|
||||
*/
|
||||
public class Point4f extends Tuple4f implements java.io.Serializable {
|
||||
|
||||
|
||||
// Compatible with 1.1
|
||||
static final long serialVersionUID = 4643134103185764459L;
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Point4f from the specified xyzw coordinates.
|
||||
*
|
||||
* @param x the x coordinate
|
||||
* @param y the y coordinate
|
||||
* @param z the z coordinate
|
||||
* @param w the w coordinate
|
||||
*/
|
||||
public Point4f(float x, float y, float z, float w) {
|
||||
super(x, y, z, w);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Point4f from the array of length 4.
|
||||
*
|
||||
* @param p the array of length 4 containing xyzw in order
|
||||
*/
|
||||
public Point4f(float[] p) {
|
||||
super(p);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Point4f from the specified Point4f.
|
||||
*
|
||||
* @param p1 the Point4f containing the initialization x y z w data
|
||||
*/
|
||||
public Point4f(Point4f p1) {
|
||||
super(p1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Point4f from the specified Point4d.
|
||||
*
|
||||
* @param p1 the Point4d containing the initialization x y z w data
|
||||
*/
|
||||
public Point4f(Point4d p1) {
|
||||
super(p1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Point4f from the specified Tuple4f.
|
||||
*
|
||||
* @param t1 the Tuple4f containing the initialization x y z w data
|
||||
*/
|
||||
public Point4f(Tuple4f t1) {
|
||||
super(t1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Point4f from the specified Tuple4d.
|
||||
*
|
||||
* @param t1 the Tuple4d containing the initialization x y z w data
|
||||
*/
|
||||
public Point4f(Tuple4d t1) {
|
||||
super(t1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Point4f from the specified Tuple3f.
|
||||
* The x,y,z components of this point are set to the corresponding
|
||||
* components of tuple t1. The w component of this point
|
||||
* is set to 1.
|
||||
*
|
||||
* @param t1 the tuple to be copied
|
||||
* @since vecmath 1.2
|
||||
*/
|
||||
public Point4f(Tuple3f t1) {
|
||||
super(t1.x, t1.y, t1.z, 1.0f);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Point4f to (0,0,0,0).
|
||||
*/
|
||||
public Point4f() {
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the x,y,z components of this point to the corresponding
|
||||
* components of tuple t1. The w component of this point
|
||||
* is set to 1.
|
||||
*
|
||||
* @param t1 the tuple to be copied
|
||||
* @since vecmath 1.2
|
||||
*/
|
||||
public final void set(Tuple3f t1) {
|
||||
this.x = t1.x;
|
||||
this.y = t1.y;
|
||||
this.z = t1.z;
|
||||
this.w = 1.0f;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Computes the square of the distance between this point and point p1.
|
||||
*
|
||||
* @param p1 the other point
|
||||
* @return the square of distance between these two points as a float
|
||||
*/
|
||||
public final float distanceSquared(Point4f p1) {
|
||||
float dx, dy, dz, dw;
|
||||
|
||||
dx = this.x - p1.x;
|
||||
dy = this.y - p1.y;
|
||||
dz = this.z - p1.z;
|
||||
dw = this.w - p1.w;
|
||||
return (dx * dx + dy * dy + dz * dz + dw * dw);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Computes the distance between this point and point p1.
|
||||
*
|
||||
* @param p1 the other point
|
||||
* @return the distance between the two points
|
||||
*/
|
||||
public final float distance(Point4f p1) {
|
||||
float dx, dy, dz, dw;
|
||||
|
||||
dx = this.x - p1.x;
|
||||
dy = this.y - p1.y;
|
||||
dz = this.z - p1.z;
|
||||
dw = this.w - p1.w;
|
||||
return (float) Math.sqrt(dx * dx + dy * dy + dz * dz + dw * dw);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Computes the L-1 (Manhattan) distance between this point and
|
||||
* point p1. The L-1 distance is equal to:
|
||||
* abs(x1-x2) + abs(y1-y2) + abs(z1-z2) + abs(w1-w2).
|
||||
*
|
||||
* @param p1 the other point
|
||||
* @return the L-1 distance
|
||||
*/
|
||||
public final float distanceL1(Point4f p1) {
|
||||
return (Math.abs(this.x - p1.x) + Math.abs(this.y - p1.y) + Math.abs(this.z - p1.z) + Math.abs(this.w - p1.w));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Computes the L-infinite distance between this point and
|
||||
* point p1. The L-infinite distance is equal to
|
||||
* MAX[abs(x1-x2), abs(y1-y2), abs(z1-z2), abs(w1-w2)].
|
||||
*
|
||||
* @param p1 the other point
|
||||
* @return the L-infinite distance
|
||||
*/
|
||||
public final float distanceLinf(Point4f p1) {
|
||||
float t1, t2;
|
||||
t1 = Math.max(Math.abs(this.x - p1.x), Math.abs(this.y - p1.y));
|
||||
t2 = Math.max(Math.abs(this.z - p1.z), Math.abs(this.w - p1.w));
|
||||
|
||||
return (Math.max(t1, t2));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies each of the x,y,z components of the Point4f parameter
|
||||
* by 1/w, places the projected values into this point, and places
|
||||
* a 1 as the w parameter of this point.
|
||||
*
|
||||
* @param p1 the source Point4f, which is not modified
|
||||
*/
|
||||
public final void project(Point4f p1) {
|
||||
float oneOw;
|
||||
|
||||
oneOw = 1 / p1.w;
|
||||
x = p1.x * oneOw;
|
||||
y = p1.y * oneOw;
|
||||
z = p1.z * oneOw;
|
||||
w = 1.0f;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
183
src/main/java/com/volmit/iris/util/math/RNG.java
Normal file
183
src/main/java/com/volmit/iris/util/math/RNG.java
Normal file
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.math;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
|
||||
public class RNG extends Random {
|
||||
private static final char[] CHARGEN = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-=!@#$%^&*()_+`~[];',./<>?:\\\"{}|\\\\".toCharArray();
|
||||
private static final long serialVersionUID = 5222938581174415179L;
|
||||
public static final RNG r = new RNG();
|
||||
private final long sx;
|
||||
|
||||
public RNG() {
|
||||
super();
|
||||
sx = 0;
|
||||
}
|
||||
|
||||
public RNG(long seed) {
|
||||
super(seed);
|
||||
this.sx = seed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a seed (long) from the hash of the seed string
|
||||
*
|
||||
* @param seed the seed (string)
|
||||
*/
|
||||
public RNG(String seed) {
|
||||
this(UUID.nameUUIDFromBytes(seed.getBytes(StandardCharsets.UTF_8)).getLeastSignificantBits() + UUID.nameUUIDFromBytes(seed.getBytes(StandardCharsets.UTF_8)).getMostSignificantBits() + (seed.length() * 32564L));
|
||||
}
|
||||
|
||||
public RNG nextParallelRNG(int signature) {
|
||||
return new RNG(sx + signature);
|
||||
}
|
||||
|
||||
public RNG nextParallelRNG(long signature) {
|
||||
return new RNG(sx + signature);
|
||||
}
|
||||
|
||||
public String s(int length) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
sb.append(c());
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public char c() {
|
||||
return CHARGEN[i(CHARGEN.length - 1)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Pick a random enum
|
||||
*
|
||||
* @param t the enum class
|
||||
* @return the enum
|
||||
*/
|
||||
public <T> T e(Class<T> t) {
|
||||
T[] c = t.getEnumConstants();
|
||||
return c[i(c.length)];
|
||||
}
|
||||
|
||||
public boolean b() {
|
||||
return nextBoolean();
|
||||
}
|
||||
|
||||
public boolean b(double percent) {
|
||||
return d() > percent;
|
||||
}
|
||||
|
||||
public short si(int lowerBound, int upperBound) {
|
||||
return (short) (lowerBound + (nextFloat() * ((upperBound - lowerBound) + 1)));
|
||||
}
|
||||
|
||||
public short si(int upperBound) {
|
||||
return si(0, upperBound);
|
||||
}
|
||||
|
||||
public short si() {
|
||||
return si(1);
|
||||
}
|
||||
|
||||
public float f(float lowerBound, float upperBound) {
|
||||
return lowerBound + (nextFloat() * ((upperBound - lowerBound)));
|
||||
}
|
||||
|
||||
public float f(float upperBound) {
|
||||
return f(0, upperBound);
|
||||
}
|
||||
|
||||
public float f() {
|
||||
return f(1);
|
||||
}
|
||||
|
||||
public double d(double lowerBound, double upperBound) {
|
||||
return M.lerp(lowerBound, upperBound, nextDouble());
|
||||
}
|
||||
|
||||
public double d(double upperBound) {
|
||||
return d(0, upperBound);
|
||||
}
|
||||
|
||||
public double d() {
|
||||
return d(1);
|
||||
}
|
||||
|
||||
public int i(int lowerBound, int upperBound) {
|
||||
return (int) Math.floor(d(lowerBound, upperBound));
|
||||
}
|
||||
|
||||
public int i(int upperBound) {
|
||||
return i(Math.min(upperBound, 0), Math.max(0, upperBound));
|
||||
}
|
||||
|
||||
public long l(long lowerBound, long upperBound) {
|
||||
return Math.round(d(lowerBound, upperBound));
|
||||
}
|
||||
|
||||
public long l(long upperBound) {
|
||||
return l(0, upperBound);
|
||||
}
|
||||
|
||||
public int imax() {
|
||||
return i(Integer.MIN_VALUE, Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
public long lmax() {
|
||||
return l(Long.MIN_VALUE, Long.MAX_VALUE);
|
||||
}
|
||||
|
||||
public float fmax() {
|
||||
return f(Float.MIN_VALUE, Float.MAX_VALUE);
|
||||
}
|
||||
|
||||
public double dmax() {
|
||||
return d(Double.MIN_VALUE, Double.MAX_VALUE);
|
||||
}
|
||||
|
||||
public short simax() {
|
||||
return si(Short.MIN_VALUE, Short.MAX_VALUE);
|
||||
}
|
||||
|
||||
public boolean chance(double chance) {
|
||||
return chance >= nextDouble();
|
||||
}
|
||||
|
||||
public <T> T pick(List<T> pieces) {
|
||||
if (pieces.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (pieces.size() == 1) {
|
||||
return pieces.get(0);
|
||||
}
|
||||
|
||||
return pieces.get(nextInt(pieces.size()));
|
||||
}
|
||||
|
||||
public long getSeed() {
|
||||
return sx;
|
||||
}
|
||||
}
|
||||
106
src/main/java/com/volmit/iris/util/math/RollingSequence.java
Normal file
106
src/main/java/com/volmit/iris/util/math/RollingSequence.java
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util;
|
||||
|
||||
import com.volmit.iris.util.math.Average;
|
||||
import com.volmit.iris.util.math.M;
|
||||
|
||||
public class RollingSequence extends Average {
|
||||
private double median;
|
||||
private double max;
|
||||
private double min;
|
||||
private boolean dirtyMedian;
|
||||
private int dirtyExtremes;
|
||||
private boolean precision;
|
||||
|
||||
public RollingSequence(int size) {
|
||||
super(size);
|
||||
median = 0;
|
||||
min = 0;
|
||||
max = 0;
|
||||
setPrecision(false);
|
||||
}
|
||||
|
||||
public double addLast(int amt) {
|
||||
double f = 0;
|
||||
|
||||
for (int i = 0; i < Math.min(values.length, amt); i++) {
|
||||
f += values[i];
|
||||
}
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
public void setPrecision(boolean p) {
|
||||
this.precision = p;
|
||||
}
|
||||
|
||||
public boolean isPrecision() {
|
||||
return precision;
|
||||
}
|
||||
|
||||
public double getMin() {
|
||||
if (dirtyExtremes > (isPrecision() ? 0 : values.length)) {
|
||||
resetExtremes();
|
||||
}
|
||||
|
||||
return min;
|
||||
}
|
||||
|
||||
public double getMax() {
|
||||
if (dirtyExtremes > (isPrecision() ? 0 : values.length)) {
|
||||
resetExtremes();
|
||||
}
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
public double getMedian() {
|
||||
if (dirtyMedian) {
|
||||
recalculateMedian();
|
||||
}
|
||||
|
||||
return median;
|
||||
}
|
||||
|
||||
private void recalculateMedian() {
|
||||
median = new KList<Double>().forceAdd(values).sort().middleValue();
|
||||
dirtyMedian = false;
|
||||
}
|
||||
|
||||
public void resetExtremes() {
|
||||
max = Integer.MIN_VALUE;
|
||||
min = Integer.MAX_VALUE;
|
||||
|
||||
for (double i : values) {
|
||||
max = M.max(max, i);
|
||||
min = M.min(min, i);
|
||||
}
|
||||
|
||||
dirtyExtremes = 0;
|
||||
}
|
||||
|
||||
public void put(double i) {
|
||||
super.put(i);
|
||||
dirtyMedian = true;
|
||||
dirtyExtremes++;
|
||||
max = M.max(max, i);
|
||||
min = M.min(min, i);
|
||||
}
|
||||
}
|
||||
24
src/main/java/com/volmit/iris/util/math/Spiraled.java
Normal file
24
src/main/java/com/volmit/iris/util/math/Spiraled.java
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.math;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface Spiraled {
|
||||
void on(int x, int z);
|
||||
}
|
||||
78
src/main/java/com/volmit/iris/util/math/Spiraler.java
Normal file
78
src/main/java/com/volmit/iris/util/math/Spiraler.java
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.math;
|
||||
|
||||
@SuppressWarnings("EmptyMethod")
|
||||
public class Spiraler {
|
||||
int x, z, dx, dz, sizeX, sizeZ, t, maxI, i;
|
||||
int ox, oz;
|
||||
private final Spiraled spiraled;
|
||||
|
||||
public Spiraler(int sizeX, int sizeZ, Spiraled spiraled) {
|
||||
ox = 0;
|
||||
oz = 0;
|
||||
this.spiraled = spiraled;
|
||||
retarget(sizeX, sizeZ);
|
||||
}
|
||||
|
||||
public void drain() {
|
||||
while (hasNext()) {
|
||||
next();
|
||||
}
|
||||
}
|
||||
|
||||
static void Spiral(int X, int Y) {
|
||||
|
||||
}
|
||||
|
||||
public Spiraler setOffset(int ox, int oz) {
|
||||
this.ox = ox;
|
||||
this.oz = oz;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void retarget(int sizeX, int sizeZ) {
|
||||
this.sizeX = sizeX;
|
||||
this.sizeZ = sizeZ;
|
||||
x = z = dx = 0;
|
||||
dz = -1;
|
||||
i = 0;
|
||||
t = Math.max(sizeX, sizeZ);
|
||||
maxI = t * t;
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
return i < maxI;
|
||||
}
|
||||
|
||||
public void next() {
|
||||
if ((-sizeX / 2 <= x) && (x <= sizeX / 2) && (-sizeZ / 2 <= z) && (z <= sizeZ / 2)) {
|
||||
spiraled.on(x + ox, z + ox);
|
||||
}
|
||||
|
||||
if ((x == z) || ((x < 0) && (x == -z)) || ((x > 0) && (x == 1 - z))) {
|
||||
t = dx;
|
||||
dx = -dz;
|
||||
dz = t;
|
||||
}
|
||||
x += dx;
|
||||
z += dz;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
561
src/main/java/com/volmit/iris/util/math/Tuple2d.java
Normal file
561
src/main/java/com/volmit/iris/util/math/Tuple2d.java
Normal file
@@ -0,0 +1,561 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.math;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
|
||||
/**
|
||||
* A generic 2-element tuple that is represented by double-precision
|
||||
* floating point x,y coordinates.
|
||||
*/
|
||||
public abstract class Tuple2d implements java.io.Serializable, Cloneable {
|
||||
|
||||
static final long serialVersionUID = 6205762482756093838L;
|
||||
|
||||
/**
|
||||
* The x coordinate.
|
||||
*/
|
||||
public double x;
|
||||
|
||||
/**
|
||||
* The y coordinate.
|
||||
*/
|
||||
public double y;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Tuple2d from the specified xy coordinates.
|
||||
*
|
||||
* @param x the x coordinate
|
||||
* @param y the y coordinate
|
||||
*/
|
||||
public Tuple2d(double x, double y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Tuple2d from the specified array.
|
||||
*
|
||||
* @param t the array of length 2 containing xy in order
|
||||
*/
|
||||
public Tuple2d(double[] t) {
|
||||
this.x = t[0];
|
||||
this.y = t[1];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Tuple2d from the specified Tuple2d.
|
||||
*
|
||||
* @param t1 the Tuple2d containing the initialization x y data
|
||||
*/
|
||||
public Tuple2d(Tuple2d t1) {
|
||||
this.x = t1.x;
|
||||
this.y = t1.y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Tuple2d from the specified Tuple2f.
|
||||
*
|
||||
* @param t1 the Tuple2f containing the initialization x y data
|
||||
*/
|
||||
public Tuple2d(Tuple2f t1) {
|
||||
this.x = t1.x;
|
||||
this.y = t1.y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Tuple2d to (0,0).
|
||||
*/
|
||||
public Tuple2d() {
|
||||
this.x = 0.0;
|
||||
this.y = 0.0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the specified xy coordinates.
|
||||
*
|
||||
* @param x the x coordinate
|
||||
* @param y the y coordinate
|
||||
*/
|
||||
public final void set(double x, double y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple from the 2 values specified in
|
||||
* the array.
|
||||
*
|
||||
* @param t the array of length 2 containing xy in order
|
||||
*/
|
||||
public final void set(double[] t) {
|
||||
this.x = t[0];
|
||||
this.y = t[1];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the value of the Tuple2d argument.
|
||||
*
|
||||
* @param t1 the tuple to be copied
|
||||
*/
|
||||
public final void set(Tuple2d t1) {
|
||||
this.x = t1.x;
|
||||
this.y = t1.y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the value of Tuple2f t1.
|
||||
*
|
||||
* @param t1 the tuple to be copied
|
||||
*/
|
||||
public final void set(Tuple2f t1) {
|
||||
this.x = t1.x;
|
||||
this.y = t1.y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the value of the elements of this tuple into the array t.
|
||||
*
|
||||
* @param t the array that will contain the values of the vector
|
||||
*/
|
||||
public final void get(double[] t) {
|
||||
t[0] = this.x;
|
||||
t[1] = this.y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the vector sum of tuples t1 and t2.
|
||||
*
|
||||
* @param t1 the first tuple
|
||||
* @param t2 the second tuple
|
||||
*/
|
||||
public final void add(Tuple2d t1, Tuple2d t2) {
|
||||
this.x = t1.x + t2.x;
|
||||
this.y = t1.y + t2.y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the vector sum of itself and tuple t1.
|
||||
*
|
||||
* @param t1 the other tuple
|
||||
*/
|
||||
public final void add(Tuple2d t1) {
|
||||
this.x += t1.x;
|
||||
this.y += t1.y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the vector difference of
|
||||
* tuple t1 and t2 (this = t1 - t2).
|
||||
*
|
||||
* @param t1 the first tuple
|
||||
* @param t2 the second tuple
|
||||
*/
|
||||
public final void sub(Tuple2d t1, Tuple2d t2) {
|
||||
this.x = t1.x - t2.x;
|
||||
this.y = t1.y - t2.y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the vector difference of
|
||||
* itself and tuple t1 (this = this - t1).
|
||||
*
|
||||
* @param t1 the other vector
|
||||
*/
|
||||
public final void sub(Tuple2d t1) {
|
||||
this.x -= t1.x;
|
||||
this.y -= t1.y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the negation of tuple t1.
|
||||
*
|
||||
* @param t1 the source vector
|
||||
*/
|
||||
public final void negate(Tuple2d t1) {
|
||||
this.x = -t1.x;
|
||||
this.y = -t1.y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Negates the value of this vector in place.
|
||||
*/
|
||||
public final void negate() {
|
||||
this.x = -this.x;
|
||||
this.y = -this.y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the scalar multiplication
|
||||
* of tuple t1.
|
||||
*
|
||||
* @param s the scalar value
|
||||
* @param t1 the source tuple
|
||||
*/
|
||||
public final void scale(double s, Tuple2d t1) {
|
||||
this.x = s * t1.x;
|
||||
this.y = s * t1.y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the scalar multiplication
|
||||
* of itself.
|
||||
*
|
||||
* @param s the scalar value
|
||||
*/
|
||||
public final void scale(double s) {
|
||||
this.x *= s;
|
||||
this.y *= s;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the scalar multiplication
|
||||
* of tuple t1 and then adds tuple t2 (this = s*t1 + t2).
|
||||
*
|
||||
* @param s the scalar value
|
||||
* @param t1 the tuple to be multipled
|
||||
* @param t2 the tuple to be added
|
||||
*/
|
||||
public final void scaleAdd(double s, Tuple2d t1, Tuple2d t2) {
|
||||
this.x = s * t1.x + t2.x;
|
||||
this.y = s * t1.y + t2.y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the scalar multiplication
|
||||
* of itself and then adds tuple t1 (this = s*this + t1).
|
||||
*
|
||||
* @param s the scalar value
|
||||
* @param t1 the tuple to be added
|
||||
*/
|
||||
public final void scaleAdd(double s, Tuple2d t1) {
|
||||
this.x = s * this.x + t1.x;
|
||||
this.y = s * this.y + t1.y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a hash code value based on the data values in this
|
||||
* object. Two different Tuple2d objects with identical data values
|
||||
* (i.e., Tuple2d.equals returns true) will return the same hash
|
||||
* code value. Two objects with different data members may return the
|
||||
* same hash value, although this is not likely.
|
||||
*
|
||||
* @return the integer hash code value
|
||||
*/
|
||||
public int hashCode() {
|
||||
long bits = 1L;
|
||||
bits = 31L * bits + VecMathUtil.doubleToLongBits(x);
|
||||
bits = 31L * bits + VecMathUtil.doubleToLongBits(y);
|
||||
return (int) (bits ^ (bits >> 32));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if all of the data members of Tuple2d t1 are
|
||||
* equal to the corresponding data members in this Tuple2d.
|
||||
*
|
||||
* @param t1 the vector with which the comparison is made
|
||||
* @return true or false
|
||||
*/
|
||||
public boolean equals(Tuple2d t1) {
|
||||
try {
|
||||
return (this.x == t1.x && this.y == t1.y);
|
||||
} catch (NullPointerException e2) {
|
||||
Iris.reportError(e2);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the Object t1 is of type Tuple2d and all of the
|
||||
* data members of t1 are equal to the corresponding data members in
|
||||
* this Tuple2d.
|
||||
*
|
||||
* @param t1 the object with which the comparison is made
|
||||
* @return true or false
|
||||
*/
|
||||
public boolean equals(Object t1) {
|
||||
try {
|
||||
Tuple2d t2 = (Tuple2d) t1;
|
||||
return (this.x == t2.x && this.y == t2.y);
|
||||
} catch (NullPointerException | ClassCastException e2) {
|
||||
Iris.reportError(e2);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the L-infinite distance between this tuple
|
||||
* and tuple t1 is less than or equal to the epsilon parameter,
|
||||
* otherwise returns false. The L-infinite
|
||||
* distance is equal to MAX[abs(x1-x2), abs(y1-y2)].
|
||||
*
|
||||
* @param t1 the tuple to be compared to this tuple
|
||||
* @param epsilon the threshold value
|
||||
* @return true or false
|
||||
*/
|
||||
public boolean epsilonEquals(Tuple2d t1, double epsilon) {
|
||||
double diff;
|
||||
|
||||
diff = x - t1.x;
|
||||
if (Double.isNaN(diff)) return false;
|
||||
if ((diff < 0 ? -diff : diff) > epsilon) return false;
|
||||
|
||||
diff = y - t1.y;
|
||||
if (Double.isNaN(diff)) return false;
|
||||
return !((diff < 0 ? -diff : diff) > epsilon);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string that contains the values of this Tuple2d.
|
||||
* The form is (x,y).
|
||||
*
|
||||
* @return the String representation
|
||||
*/
|
||||
public String toString() {
|
||||
return ("(" + this.x + ", " + this.y + ")");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clamps the tuple parameter to the range [low, high] and
|
||||
* places the values into this tuple.
|
||||
*
|
||||
* @param min the lowest value in the tuple after clamping
|
||||
* @param max the highest value in the tuple after clamping
|
||||
* @param t the source tuple, which will not be modified
|
||||
*/
|
||||
public final void clamp(double min, double max, Tuple2d t) {
|
||||
if (t.x > max) {
|
||||
x = max;
|
||||
} else x = Math.max(t.x, min);
|
||||
|
||||
if (t.y > max) {
|
||||
y = max;
|
||||
} else y = Math.max(t.y, min);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clamps the minimum value of the tuple parameter to the min
|
||||
* parameter and places the values into this tuple.
|
||||
*
|
||||
* @param min the lowest value in the tuple after clamping
|
||||
* @param t the source tuple, which will not be modified
|
||||
*/
|
||||
public final void clampMin(double min, Tuple2d t) {
|
||||
x = Math.max(t.x, min);
|
||||
|
||||
y = Math.max(t.y, min);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clamps the maximum value of the tuple parameter to the max
|
||||
* parameter and places the values into this tuple.
|
||||
*
|
||||
* @param max the highest value in the tuple after clamping
|
||||
* @param t the source tuple, which will not be modified
|
||||
*/
|
||||
public final void clampMax(double max, Tuple2d t) {
|
||||
x = Math.min(t.x, max);
|
||||
|
||||
y = Math.min(t.y, max);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets each component of the tuple parameter to its absolute
|
||||
* value and places the modified values into this tuple.
|
||||
*
|
||||
* @param t the source tuple, which will not be modified
|
||||
*/
|
||||
public final void absolute(Tuple2d t) {
|
||||
x = Math.abs(t.x);
|
||||
y = Math.abs(t.y);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clamps this tuple to the range [low, high].
|
||||
*
|
||||
* @param min the lowest value in this tuple after clamping
|
||||
* @param max the highest value in this tuple after clamping
|
||||
*/
|
||||
public final void clamp(double min, double max) {
|
||||
if (x > max) {
|
||||
x = max;
|
||||
} else if (x < min) {
|
||||
x = min;
|
||||
}
|
||||
|
||||
if (y > max) {
|
||||
y = max;
|
||||
} else if (y < min) {
|
||||
y = min;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clamps the minimum value of this tuple to the min parameter.
|
||||
*
|
||||
* @param min the lowest value in this tuple after clamping
|
||||
*/
|
||||
public final void clampMin(double min) {
|
||||
if (x < min) x = min;
|
||||
if (y < min) y = min;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clamps the maximum value of this tuple to the max parameter.
|
||||
*
|
||||
* @param max the highest value in the tuple after clamping
|
||||
*/
|
||||
public final void clampMax(double max) {
|
||||
if (x > max) x = max;
|
||||
if (y > max) y = max;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets each component of this tuple to its absolute value.
|
||||
*/
|
||||
public final void absolute() {
|
||||
x = Math.abs(x);
|
||||
y = Math.abs(y);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Linearly interpolates between tuples t1 and t2 and places the
|
||||
* result into this tuple: this = (1-alpha)*t1 + alpha*t2.
|
||||
*
|
||||
* @param t1 the first tuple
|
||||
* @param t2 the second tuple
|
||||
* @param alpha the alpha interpolation parameter
|
||||
*/
|
||||
public final void interpolate(Tuple2d t1, Tuple2d t2, double alpha) {
|
||||
this.x = (1 - alpha) * t1.x + alpha * t2.x;
|
||||
this.y = (1 - alpha) * t1.y + alpha * t2.y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Linearly interpolates between this tuple and tuple t1 and
|
||||
* places the result into this tuple: this = (1-alpha)*this + alpha*t1.
|
||||
*
|
||||
* @param t1 the first tuple
|
||||
* @param alpha the alpha interpolation parameter
|
||||
*/
|
||||
public final void interpolate(Tuple2d t1, double alpha) {
|
||||
this.x = (1 - alpha) * this.x + alpha * t1.x;
|
||||
this.y = (1 - alpha) * this.y + alpha * t1.y;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new object of the same class as this object.
|
||||
*
|
||||
* @return a clone of this instance.
|
||||
* @throws OutOfMemoryError if there is not enough memory.
|
||||
* @see java.lang.Cloneable
|
||||
* @since vecmath 1.3
|
||||
*/
|
||||
public Object clone() {
|
||||
// Since there are no arrays we can just use Object.clone()
|
||||
try {
|
||||
return super.clone();
|
||||
} catch (CloneNotSupportedException e) {Iris.reportError(e);
|
||||
// this shouldn't happen, since we are Cloneable
|
||||
throw new InternalError();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the <i>x</i> coordinate.
|
||||
*
|
||||
* @return the <i>x</i> coordinate.
|
||||
* @since vecmath 1.5
|
||||
*/
|
||||
public final double getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the <i>x</i> coordinate.
|
||||
*
|
||||
* @param x value to <i>x</i> coordinate.
|
||||
* @since vecmath 1.5
|
||||
*/
|
||||
public final void setX(double x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the <i>y</i> coordinate.
|
||||
*
|
||||
* @return the <i>y</i> coordinate.
|
||||
* @since vecmath 1.5
|
||||
*/
|
||||
public final double getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the <i>y</i> coordinate.
|
||||
*
|
||||
* @param y value to <i>y</i> coordinate.
|
||||
* @since vecmath 1.5
|
||||
*/
|
||||
public final void setY(double y) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
}
|
||||
564
src/main/java/com/volmit/iris/util/math/Tuple2f.java
Normal file
564
src/main/java/com/volmit/iris/util/math/Tuple2f.java
Normal file
@@ -0,0 +1,564 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.math;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
|
||||
/**
|
||||
* A generic 2-element tuple that is represented by single-precision
|
||||
* floating point x,y coordinates.
|
||||
*/
|
||||
public abstract class Tuple2f implements java.io.Serializable, Cloneable {
|
||||
|
||||
static final long serialVersionUID = 9011180388985266884L;
|
||||
|
||||
/**
|
||||
* The x coordinate.
|
||||
*/
|
||||
public float x;
|
||||
|
||||
/**
|
||||
* The y coordinate.
|
||||
*/
|
||||
public float y;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Tuple2f from the specified xy coordinates.
|
||||
*
|
||||
* @param x the x coordinate
|
||||
* @param y the y coordinate
|
||||
*/
|
||||
public Tuple2f(float x, float y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Tuple2f from the specified array.
|
||||
*
|
||||
* @param t the array of length 2 containing xy in order
|
||||
*/
|
||||
public Tuple2f(float[] t) {
|
||||
this.x = t[0];
|
||||
this.y = t[1];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Tuple2f from the specified Tuple2f.
|
||||
*
|
||||
* @param t1 the Tuple2f containing the initialization x y data
|
||||
*/
|
||||
public Tuple2f(Tuple2f t1) {
|
||||
this.x = t1.x;
|
||||
this.y = t1.y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Tuple2f from the specified Tuple2d.
|
||||
*
|
||||
* @param t1 the Tuple2d containing the initialization x y data
|
||||
*/
|
||||
public Tuple2f(Tuple2d t1) {
|
||||
this.x = (float) t1.x;
|
||||
this.y = (float) t1.y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Tuple2f to (0,0).
|
||||
*/
|
||||
public Tuple2f() {
|
||||
this.x = (float) 0.0;
|
||||
this.y = (float) 0.0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the specified xy coordinates.
|
||||
*
|
||||
* @param x the x coordinate
|
||||
* @param y the y coordinate
|
||||
*/
|
||||
public final void set(float x, float y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple from the 2 values specified in
|
||||
* the array.
|
||||
*
|
||||
* @param t the array of length 2 containing xy in order
|
||||
*/
|
||||
public final void set(float[] t) {
|
||||
this.x = t[0];
|
||||
this.y = t[1];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the value of the Tuple2f argument.
|
||||
*
|
||||
* @param t1 the tuple to be copied
|
||||
*/
|
||||
public final void set(Tuple2f t1) {
|
||||
this.x = t1.x;
|
||||
this.y = t1.y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the value of the Tuple2d argument.
|
||||
*
|
||||
* @param t1 the tuple to be copied
|
||||
*/
|
||||
public final void set(Tuple2d t1) {
|
||||
this.x = (float) t1.x;
|
||||
this.y = (float) t1.y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copies the value of the elements of this tuple into the array t.
|
||||
*
|
||||
* @param t the array that will contain the values of the vector
|
||||
*/
|
||||
public final void get(float[] t) {
|
||||
t[0] = this.x;
|
||||
t[1] = this.y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the vector sum of tuples t1 and t2.
|
||||
*
|
||||
* @param t1 the first tuple
|
||||
* @param t2 the second tuple
|
||||
*/
|
||||
public final void add(Tuple2f t1, Tuple2f t2) {
|
||||
this.x = t1.x + t2.x;
|
||||
this.y = t1.y + t2.y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the vector sum of itself and tuple t1.
|
||||
*
|
||||
* @param t1 the other tuple
|
||||
*/
|
||||
public final void add(Tuple2f t1) {
|
||||
this.x += t1.x;
|
||||
this.y += t1.y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the vector difference of
|
||||
* tuple t1 and t2 (this = t1 - t2).
|
||||
*
|
||||
* @param t1 the first tuple
|
||||
* @param t2 the second tuple
|
||||
*/
|
||||
public final void sub(Tuple2f t1, Tuple2f t2) {
|
||||
this.x = t1.x - t2.x;
|
||||
this.y = t1.y - t2.y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the vector difference of
|
||||
* itself and tuple t1 (this = this - t1).
|
||||
*
|
||||
* @param t1 the other tuple
|
||||
*/
|
||||
public final void sub(Tuple2f t1) {
|
||||
this.x -= t1.x;
|
||||
this.y -= t1.y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the negation of tuple t1.
|
||||
*
|
||||
* @param t1 the source tuple
|
||||
*/
|
||||
public final void negate(Tuple2f t1) {
|
||||
this.x = -t1.x;
|
||||
this.y = -t1.y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Negates the value of this vector in place.
|
||||
*/
|
||||
public final void negate() {
|
||||
this.x = -this.x;
|
||||
this.y = -this.y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the scalar multiplication
|
||||
* of tuple t1.
|
||||
*
|
||||
* @param s the scalar value
|
||||
* @param t1 the source tuple
|
||||
*/
|
||||
public final void scale(float s, Tuple2f t1) {
|
||||
this.x = s * t1.x;
|
||||
this.y = s * t1.y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the scalar multiplication
|
||||
* of itself.
|
||||
*
|
||||
* @param s the scalar value
|
||||
*/
|
||||
public final void scale(float s) {
|
||||
this.x *= s;
|
||||
this.y *= s;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the scalar multiplication
|
||||
* of tuple t1 and then adds tuple t2 (this = s*t1 + t2).
|
||||
*
|
||||
* @param s the scalar value
|
||||
* @param t1 the tuple to be multipled
|
||||
* @param t2 the tuple to be added
|
||||
*/
|
||||
public final void scaleAdd(float s, Tuple2f t1, Tuple2f t2) {
|
||||
this.x = s * t1.x + t2.x;
|
||||
this.y = s * t1.y + t2.y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the scalar multiplication
|
||||
* of itself and then adds tuple t1 (this = s*this + t1).
|
||||
*
|
||||
* @param s the scalar value
|
||||
* @param t1 the tuple to be added
|
||||
*/
|
||||
public final void scaleAdd(float s, Tuple2f t1) {
|
||||
this.x = s * this.x + t1.x;
|
||||
this.y = s * this.y + t1.y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a hash code value based on the data values in this
|
||||
* object. Two different Tuple2f objects with identical data values
|
||||
* (i.e., Tuple2f.equals returns true) will return the same hash
|
||||
* code value. Two objects with different data members may return the
|
||||
* same hash value, although this is not likely.
|
||||
*
|
||||
* @return the integer hash code value
|
||||
*/
|
||||
public int hashCode() {
|
||||
long bits = 1L;
|
||||
bits = 31L * bits + (long) VecMathUtil.floatToIntBits(x);
|
||||
bits = 31L * bits + (long) VecMathUtil.floatToIntBits(y);
|
||||
return (int) (bits ^ (bits >> 32));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if all of the data members of Tuple2f t1 are
|
||||
* equal to the corresponding data members in this Tuple2f.
|
||||
*
|
||||
* @param t1 the vector with which the comparison is made
|
||||
* @return true or false
|
||||
*/
|
||||
public boolean equals(Tuple2f t1) {
|
||||
try {
|
||||
return (this.x == t1.x && this.y == t1.y);
|
||||
} catch (NullPointerException e2) {
|
||||
Iris.reportError(e2);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the Object t1 is of type Tuple2f and all of the
|
||||
* data members of t1 are equal to the corresponding data members in
|
||||
* this Tuple2f.
|
||||
*
|
||||
* @param t1 the object with which the comparison is made
|
||||
* @return true or false
|
||||
*/
|
||||
public boolean equals(Object t1) {
|
||||
try {
|
||||
Tuple2f t2 = (Tuple2f) t1;
|
||||
return (this.x == t2.x && this.y == t2.y);
|
||||
} catch (NullPointerException | ClassCastException e2) {
|
||||
Iris.reportError(e2);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the L-infinite distance between this tuple
|
||||
* and tuple t1 is less than or equal to the epsilon parameter,
|
||||
* otherwise returns false. The L-infinite
|
||||
* distance is equal to MAX[abs(x1-x2), abs(y1-y2)].
|
||||
*
|
||||
* @param t1 the tuple to be compared to this tuple
|
||||
* @param epsilon the threshold value
|
||||
* @return true or false
|
||||
*/
|
||||
public boolean epsilonEquals(Tuple2f t1, float epsilon) {
|
||||
float diff;
|
||||
|
||||
diff = x - t1.x;
|
||||
if (Float.isNaN(diff)) return false;
|
||||
if ((diff < 0 ? -diff : diff) > epsilon) return false;
|
||||
|
||||
diff = y - t1.y;
|
||||
if (Float.isNaN(diff)) return false;
|
||||
return !((diff < 0 ? -diff : diff) > epsilon);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string that contains the values of this Tuple2f.
|
||||
* The form is (x,y).
|
||||
*
|
||||
* @return the String representation
|
||||
*/
|
||||
public String toString() {
|
||||
return ("(" + this.x + ", " + this.y + ")");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clamps the tuple parameter to the range [low, high] and
|
||||
* places the values into this tuple.
|
||||
*
|
||||
* @param min the lowest value in the tuple after clamping
|
||||
* @param max the highest value in the tuple after clamping
|
||||
* @param t the source tuple, which will not be modified
|
||||
*/
|
||||
public final void clamp(float min, float max, Tuple2f t) {
|
||||
if (t.x > max) {
|
||||
x = max;
|
||||
} else x = Math.max(t.x, min);
|
||||
|
||||
if (t.y > max) {
|
||||
y = max;
|
||||
} else y = Math.max(t.y, min);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clamps the minimum value of the tuple parameter to the min
|
||||
* parameter and places the values into this tuple.
|
||||
*
|
||||
* @param min the lowest value in the tuple after clamping
|
||||
* @param t the source tuple, which will not be modified
|
||||
*/
|
||||
public final void clampMin(float min, Tuple2f t) {
|
||||
x = Math.max(t.x, min);
|
||||
|
||||
y = Math.max(t.y, min);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clamps the maximum value of the tuple parameter to the max
|
||||
* parameter and places the values into this tuple.
|
||||
*
|
||||
* @param max the highest value in the tuple after clamping
|
||||
* @param t the source tuple, which will not be modified
|
||||
*/
|
||||
public final void clampMax(float max, Tuple2f t) {
|
||||
x = Math.min(t.x, max);
|
||||
|
||||
y = Math.min(t.y, max);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets each component of the tuple parameter to its absolute
|
||||
* value and places the modified values into this tuple.
|
||||
*
|
||||
* @param t the source tuple, which will not be modified
|
||||
*/
|
||||
public final void absolute(Tuple2f t) {
|
||||
x = Math.abs(t.x);
|
||||
y = Math.abs(t.y);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clamps this tuple to the range [low, high].
|
||||
*
|
||||
* @param min the lowest value in this tuple after clamping
|
||||
* @param max the highest value in this tuple after clamping
|
||||
*/
|
||||
public final void clamp(float min, float max) {
|
||||
if (x > max) {
|
||||
x = max;
|
||||
} else if (x < min) {
|
||||
x = min;
|
||||
}
|
||||
|
||||
if (y > max) {
|
||||
y = max;
|
||||
} else if (y < min) {
|
||||
y = min;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clamps the minimum value of this tuple to the min parameter.
|
||||
*
|
||||
* @param min the lowest value in this tuple after clamping
|
||||
*/
|
||||
public final void clampMin(float min) {
|
||||
if (x < min) x = min;
|
||||
if (y < min) y = min;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clamps the maximum value of this tuple to the max parameter.
|
||||
*
|
||||
* @param max the highest value in the tuple after clamping
|
||||
*/
|
||||
public final void clampMax(float max) {
|
||||
if (x > max) x = max;
|
||||
if (y > max) y = max;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets each component of this tuple to its absolute value.
|
||||
*/
|
||||
public final void absolute() {
|
||||
x = Math.abs(x);
|
||||
y = Math.abs(y);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Linearly interpolates between tuples t1 and t2 and places the
|
||||
* result into this tuple: this = (1-alpha)*t1 + alpha*t2.
|
||||
*
|
||||
* @param t1 the first tuple
|
||||
* @param t2 the second tuple
|
||||
* @param alpha the alpha interpolation parameter
|
||||
*/
|
||||
public final void interpolate(Tuple2f t1, Tuple2f t2, float alpha) {
|
||||
this.x = (1 - alpha) * t1.x + alpha * t2.x;
|
||||
this.y = (1 - alpha) * t1.y + alpha * t2.y;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Linearly interpolates between this tuple and tuple t1 and
|
||||
* places the result into this tuple: this = (1-alpha)*this + alpha*t1.
|
||||
*
|
||||
* @param t1 the first tuple
|
||||
* @param alpha the alpha interpolation parameter
|
||||
*/
|
||||
public final void interpolate(Tuple2f t1, float alpha) {
|
||||
|
||||
this.x = (1 - alpha) * this.x + alpha * t1.x;
|
||||
this.y = (1 - alpha) * this.y + alpha * t1.y;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new object of the same class as this object.
|
||||
*
|
||||
* @return a clone of this instance.
|
||||
* @throws OutOfMemoryError if there is not enough memory.
|
||||
* @see java.lang.Cloneable
|
||||
* @since vecmath 1.3
|
||||
*/
|
||||
public Object clone() {
|
||||
// Since there are no arrays we can just use Object.clone()
|
||||
try {
|
||||
return super.clone();
|
||||
} catch (CloneNotSupportedException e) {Iris.reportError(e);
|
||||
// this shouldn't happen, since we are Cloneable
|
||||
throw new InternalError();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the <i>x</i> coordinate.
|
||||
*
|
||||
* @return the <i>x</i> coordinate.
|
||||
* @since vecmath 1.5
|
||||
*/
|
||||
public final float getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the <i>x</i> coordinate.
|
||||
*
|
||||
* @param x value to <i>x</i> coordinate.
|
||||
* @since vecmath 1.5
|
||||
*/
|
||||
public final void setX(float x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the <i>y</i> coordinate.
|
||||
*
|
||||
* @return the <i>y</i> coordinate.
|
||||
* @since vecmath 1.5
|
||||
*/
|
||||
public final float getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the <i>y</i> coordinate.
|
||||
*
|
||||
* @param y value to <i>y</i> coordinate.
|
||||
* @since vecmath 1.5
|
||||
*/
|
||||
public final void setY(float y) {
|
||||
this.y = y;
|
||||
}
|
||||
}
|
||||
711
src/main/java/com/volmit/iris/util/math/Tuple3d.java
Normal file
711
src/main/java/com/volmit/iris/util/math/Tuple3d.java
Normal file
@@ -0,0 +1,711 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.math;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
|
||||
/**
|
||||
* A generic 3-element tuple that is represented by double-precision
|
||||
* floating point x,y,z coordinates.
|
||||
*/
|
||||
public abstract class Tuple3d implements java.io.Serializable, Cloneable {
|
||||
|
||||
static final long serialVersionUID = 5542096614926168415L;
|
||||
|
||||
/**
|
||||
* The x coordinate.
|
||||
*/
|
||||
public double x;
|
||||
|
||||
/**
|
||||
* The y coordinate.
|
||||
*/
|
||||
public double y;
|
||||
|
||||
/**
|
||||
* The z coordinate.
|
||||
*/
|
||||
public double z;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Tuple3d from the specified xyz coordinates.
|
||||
*
|
||||
* @param x the x coordinate
|
||||
* @param y the y coordinate
|
||||
* @param z the z coordinate
|
||||
*/
|
||||
public Tuple3d(double x, double y, double z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Tuple3d from the array of length 3.
|
||||
*
|
||||
* @param t the array of length 3 containing xyz in order
|
||||
*/
|
||||
public Tuple3d(double[] t) {
|
||||
this.x = t[0];
|
||||
this.y = t[1];
|
||||
this.z = t[2];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Tuple3d from the specified Tuple3d.
|
||||
*
|
||||
* @param t1 the Tuple3d containing the initialization x y z data
|
||||
*/
|
||||
public Tuple3d(Tuple3d t1) {
|
||||
this.x = t1.x;
|
||||
this.y = t1.y;
|
||||
this.z = t1.z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Tuple3d from the specified Tuple3f.
|
||||
*
|
||||
* @param t1 the Tuple3f containing the initialization x y z data
|
||||
*/
|
||||
public Tuple3d(Tuple3f t1) {
|
||||
this.x = t1.x;
|
||||
this.y = t1.y;
|
||||
this.z = t1.z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Tuple3d to (0,0,0).
|
||||
*/
|
||||
public Tuple3d() {
|
||||
this.x = 0.0;
|
||||
this.y = 0.0;
|
||||
this.z = 0.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the specified xyz coordinates.
|
||||
*
|
||||
* @param x the x coordinate
|
||||
* @param y the y coordinate
|
||||
* @param z the z coordinate
|
||||
*/
|
||||
public final void set(double x, double y, double z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the value of the xyz coordinates
|
||||
* located in the array of length 3.
|
||||
*
|
||||
* @param t the array of length 3 containing xyz in order
|
||||
*/
|
||||
public final void set(double[] t) {
|
||||
this.x = t[0];
|
||||
this.y = t[1];
|
||||
this.z = t[2];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the value of tuple t1.
|
||||
*
|
||||
* @param t1 the tuple to be copied
|
||||
*/
|
||||
public final void set(Tuple3d t1) {
|
||||
this.x = t1.x;
|
||||
this.y = t1.y;
|
||||
this.z = t1.z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the value of tuple t1.
|
||||
*
|
||||
* @param t1 the tuple to be copied
|
||||
*/
|
||||
public final void set(Tuple3f t1) {
|
||||
this.x = t1.x;
|
||||
this.y = t1.y;
|
||||
this.z = t1.z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the x,y,z coordinates of this tuple into the array t
|
||||
* of length 3.
|
||||
*
|
||||
* @param t the target array
|
||||
*/
|
||||
public final void get(double[] t) {
|
||||
t[0] = this.x;
|
||||
t[1] = this.y;
|
||||
t[2] = this.z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copies the x,y,z coordinates of this tuple into the tuple t.
|
||||
*
|
||||
* @param t the Tuple3d object into which the values of this object are copied
|
||||
*/
|
||||
public final void get(Tuple3d t) {
|
||||
t.x = this.x;
|
||||
t.y = this.y;
|
||||
t.z = this.z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the sum of tuples t1 and t2.
|
||||
*
|
||||
* @param t1 the first tuple
|
||||
* @param t2 the second tuple
|
||||
*/
|
||||
public final void add(Tuple3d t1, Tuple3d t2) {
|
||||
this.x = t1.x + t2.x;
|
||||
this.y = t1.y + t2.y;
|
||||
this.z = t1.z + t2.z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the sum of itself and t1.
|
||||
*
|
||||
* @param t1 the other tuple
|
||||
*/
|
||||
public final void add(Tuple3d t1) {
|
||||
this.x += t1.x;
|
||||
this.y += t1.y;
|
||||
this.z += t1.z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the difference of tuples
|
||||
* t1 and t2 (this = t1 - t2).
|
||||
*
|
||||
* @param t1 the first tuple
|
||||
* @param t2 the second tuple
|
||||
*/
|
||||
public final void sub(Tuple3d t1, Tuple3d t2) {
|
||||
this.x = t1.x - t2.x;
|
||||
this.y = t1.y - t2.y;
|
||||
this.z = t1.z - t2.z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the difference
|
||||
* of itself and t1 (this = this - t1).
|
||||
*
|
||||
* @param t1 the other tuple
|
||||
*/
|
||||
public final void sub(Tuple3d t1) {
|
||||
this.x -= t1.x;
|
||||
this.y -= t1.y;
|
||||
this.z -= t1.z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the negation of tuple t1.
|
||||
*
|
||||
* @param t1 the source tuple
|
||||
*/
|
||||
public final void negate(Tuple3d t1) {
|
||||
this.x = -t1.x;
|
||||
this.y = -t1.y;
|
||||
this.z = -t1.z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Negates the value of this tuple in place.
|
||||
*/
|
||||
public final void negate() {
|
||||
this.x = -this.x;
|
||||
this.y = -this.y;
|
||||
this.z = -this.z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the scalar multiplication
|
||||
* of tuple t1.
|
||||
*
|
||||
* @param s the scalar value
|
||||
* @param t1 the source tuple
|
||||
*/
|
||||
public final void scale(double s, Tuple3d t1) {
|
||||
this.x = s * t1.x;
|
||||
this.y = s * t1.y;
|
||||
this.z = s * t1.z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the scalar multiplication
|
||||
* of itself.
|
||||
*
|
||||
* @param s the scalar value
|
||||
*/
|
||||
public final void scale(double s) {
|
||||
this.x *= s;
|
||||
this.y *= s;
|
||||
this.z *= s;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the scalar multiplication
|
||||
* of tuple t1 and then adds tuple t2 (this = s*t1 + t2).
|
||||
*
|
||||
* @param s the scalar value
|
||||
* @param t1 the tuple to be multipled
|
||||
* @param t2 the tuple to be added
|
||||
*/
|
||||
public final void scaleAdd(double s, Tuple3d t1, Tuple3d t2) {
|
||||
this.x = s * t1.x + t2.x;
|
||||
this.y = s * t1.y + t2.y;
|
||||
this.z = s * t1.z + t2.z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated Use scaleAdd(double,Tuple3d) instead
|
||||
*/
|
||||
public final void scaleAdd(double s, Tuple3f t1) {
|
||||
scaleAdd(s, new Point3d(t1));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the scalar multiplication
|
||||
* of itself and then adds tuple t1 (this = s*this + t1).
|
||||
*
|
||||
* @param s the scalar value
|
||||
* @param t1 the tuple to be added
|
||||
*/
|
||||
public final void scaleAdd(double s, Tuple3d t1) {
|
||||
this.x = s * this.x + t1.x;
|
||||
this.y = s * this.y + t1.y;
|
||||
this.z = s * this.z + t1.z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string that contains the values of this Tuple3d.
|
||||
* The form is (x,y,z).
|
||||
*
|
||||
* @return the String representation
|
||||
*/
|
||||
public String toString() {
|
||||
return "(" + this.x + ", " + this.y + ", " + this.z + ")";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a hash code value based on the data values in this
|
||||
* object. Two different Tuple3d objects with identical data values
|
||||
* (i.e., Tuple3d.equals returns true) will return the same hash
|
||||
* code value. Two objects with different data members may return the
|
||||
* same hash value, although this is not likely.
|
||||
*
|
||||
* @return the integer hash code value
|
||||
*/
|
||||
public int hashCode() {
|
||||
long bits = 1L;
|
||||
bits = 31L * bits + VecMathUtil.doubleToLongBits(x);
|
||||
bits = 31L * bits + VecMathUtil.doubleToLongBits(y);
|
||||
bits = 31L * bits + VecMathUtil.doubleToLongBits(z);
|
||||
return (int) (bits ^ (bits >> 32));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if all of the data members of Tuple3d t1 are
|
||||
* equal to the corresponding data members in this Tuple3d.
|
||||
*
|
||||
* @param t1 the tuple with which the comparison is made
|
||||
* @return true or false
|
||||
*/
|
||||
public boolean equals(Tuple3d t1) {
|
||||
try {
|
||||
return (this.x == t1.x && this.y == t1.y && this.z == t1.z);
|
||||
} catch (NullPointerException e2) {
|
||||
Iris.reportError(e2);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the Object t1 is of type Tuple3d and all of the
|
||||
* data members of t1 are equal to the corresponding data members in
|
||||
* this Tuple3d.
|
||||
*
|
||||
* @param t1 the Object with which the comparison is made
|
||||
* @return true or false
|
||||
*/
|
||||
public boolean equals(Object t1) {
|
||||
try {
|
||||
Tuple3d t2 = (Tuple3d) t1;
|
||||
return (this.x == t2.x && this.y == t2.y && this.z == t2.z);
|
||||
} catch (ClassCastException | NullPointerException e1) {
|
||||
Iris.reportError(e1);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the L-infinite distance between this tuple
|
||||
* and tuple t1 is less than or equal to the epsilon parameter,
|
||||
* otherwise returns false. The L-infinite
|
||||
* distance is equal to MAX[abs(x1-x2), abs(y1-y2), abs(z1-z2)].
|
||||
*
|
||||
* @param t1 the tuple to be compared to this tuple
|
||||
* @param epsilon the threshold value
|
||||
* @return true or false
|
||||
*/
|
||||
public boolean epsilonEquals(Tuple3d t1, double epsilon) {
|
||||
double diff;
|
||||
|
||||
diff = x - t1.x;
|
||||
if (Double.isNaN(diff)) return false;
|
||||
if ((diff < 0 ? -diff : diff) > epsilon) return false;
|
||||
|
||||
diff = y - t1.y;
|
||||
if (Double.isNaN(diff)) return false;
|
||||
if ((diff < 0 ? -diff : diff) > epsilon) return false;
|
||||
|
||||
diff = z - t1.z;
|
||||
if (Double.isNaN(diff)) return false;
|
||||
return !((diff < 0 ? -diff : diff) > epsilon);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated Use clamp(double,double,Tuple3d) instead
|
||||
*/
|
||||
public final void clamp(float min, float max, Tuple3d t) {
|
||||
clamp(min, (double) max, t);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clamps the tuple parameter to the range [low, high] and
|
||||
* places the values into this tuple.
|
||||
*
|
||||
* @param min the lowest value in the tuple after clamping
|
||||
* @param max the highest value in the tuple after clamping
|
||||
* @param t the source tuple, which will not be modified
|
||||
*/
|
||||
public final void clamp(double min, double max, Tuple3d t) {
|
||||
if (t.x > max) {
|
||||
x = max;
|
||||
} else x = Math.max(t.x, min);
|
||||
|
||||
if (t.y > max) {
|
||||
y = max;
|
||||
} else y = Math.max(t.y, min);
|
||||
|
||||
if (t.z > max) {
|
||||
z = max;
|
||||
} else z = Math.max(t.z, min);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated Use clampMin(double,Tuple3d) instead
|
||||
*/
|
||||
public final void clampMin(float min, Tuple3d t) {
|
||||
clampMin((double) min, t);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clamps the minimum value of the tuple parameter to the min
|
||||
* parameter and places the values into this tuple.
|
||||
*
|
||||
* @param min the lowest value in the tuple after clamping
|
||||
* @param t the source tuple, which will not be modified
|
||||
*/
|
||||
public final void clampMin(double min, Tuple3d t) {
|
||||
x = Math.max(t.x, min);
|
||||
|
||||
y = Math.max(t.y, min);
|
||||
|
||||
z = Math.max(t.z, min);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated Use clampMax(double,Tuple3d) instead
|
||||
*/
|
||||
public final void clampMax(float max, Tuple3d t) {
|
||||
clampMax((double) max, t);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clamps the maximum value of the tuple parameter to the max
|
||||
* parameter and places the values into this tuple.
|
||||
*
|
||||
* @param max the highest value in the tuple after clamping
|
||||
* @param t the source tuple, which will not be modified
|
||||
*/
|
||||
public final void clampMax(double max, Tuple3d t) {
|
||||
x = Math.min(t.x, max);
|
||||
|
||||
y = Math.min(t.y, max);
|
||||
|
||||
z = Math.min(t.z, max);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets each component of the tuple parameter to its absolute
|
||||
* value and places the modified values into this tuple.
|
||||
*
|
||||
* @param t the source tuple, which will not be modified
|
||||
*/
|
||||
public final void absolute(Tuple3d t) {
|
||||
x = Math.abs(t.x);
|
||||
y = Math.abs(t.y);
|
||||
z = Math.abs(t.z);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated Use clamp(double,double) instead
|
||||
*/
|
||||
public final void clamp(float min, float max) {
|
||||
clamp(min, (double) max);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clamps this tuple to the range [low, high].
|
||||
*
|
||||
* @param min the lowest value in this tuple after clamping
|
||||
* @param max the highest value in this tuple after clamping
|
||||
*/
|
||||
public final void clamp(double min, double max) {
|
||||
if (x > max) {
|
||||
x = max;
|
||||
} else if (x < min) {
|
||||
x = min;
|
||||
}
|
||||
|
||||
if (y > max) {
|
||||
y = max;
|
||||
} else if (y < min) {
|
||||
y = min;
|
||||
}
|
||||
|
||||
if (z > max) {
|
||||
z = max;
|
||||
} else if (z < min) {
|
||||
z = min;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated Use clampMin(double) instead
|
||||
*/
|
||||
public final void clampMin(float min) {
|
||||
clampMin((double) min);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clamps the minimum value of this tuple to the min parameter.
|
||||
*
|
||||
* @param min the lowest value in this tuple after clamping
|
||||
*/
|
||||
public final void clampMin(double min) {
|
||||
if (x < min) x = min;
|
||||
if (y < min) y = min;
|
||||
if (z < min) z = min;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated Use clampMax(double) instead
|
||||
*/
|
||||
public final void clampMax(float max) {
|
||||
clampMax((double) max);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clamps the maximum value of this tuple to the max parameter.
|
||||
*
|
||||
* @param max the highest value in the tuple after clamping
|
||||
*/
|
||||
public final void clampMax(double max) {
|
||||
if (x > max) x = max;
|
||||
if (y > max) y = max;
|
||||
if (z > max) z = max;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets each component of this tuple to its absolute value.
|
||||
*/
|
||||
public final void absolute() {
|
||||
x = Math.abs(x);
|
||||
y = Math.abs(y);
|
||||
z = Math.abs(z);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated Use interpolate(Tuple3d,Tuple3d,double) instead
|
||||
*/
|
||||
public final void interpolate(Tuple3d t1, Tuple3d t2, float alpha) {
|
||||
interpolate(t1, t2, (double) alpha);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Linearly interpolates between tuples t1 and t2 and places the
|
||||
* result into this tuple: this = (1-alpha)*t1 + alpha*t2.
|
||||
*
|
||||
* @param t1 the first tuple
|
||||
* @param t2 the second tuple
|
||||
* @param alpha the alpha interpolation parameter
|
||||
*/
|
||||
public final void interpolate(Tuple3d t1, Tuple3d t2, double alpha) {
|
||||
this.x = (1 - alpha) * t1.x + alpha * t2.x;
|
||||
this.y = (1 - alpha) * t1.y + alpha * t2.y;
|
||||
this.z = (1 - alpha) * t1.z + alpha * t2.z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated Use interpolate(Tuple3d,double) instead
|
||||
*/
|
||||
public final void interpolate(Tuple3d t1, float alpha) {
|
||||
interpolate(t1, (double) alpha);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Linearly interpolates between this tuple and tuple t1 and
|
||||
* places the result into this tuple: this = (1-alpha)*this + alpha*t1.
|
||||
*
|
||||
* @param t1 the first tuple
|
||||
* @param alpha the alpha interpolation parameter
|
||||
*/
|
||||
public final void interpolate(Tuple3d t1, double alpha) {
|
||||
this.x = (1 - alpha) * this.x + alpha * t1.x;
|
||||
this.y = (1 - alpha) * this.y + alpha * t1.y;
|
||||
this.z = (1 - alpha) * this.z + alpha * t1.z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new object of the same class as this object.
|
||||
*
|
||||
* @return a clone of this instance.
|
||||
* @throws OutOfMemoryError if there is not enough memory.
|
||||
* @see java.lang.Cloneable
|
||||
* @since vecmath 1.3
|
||||
*/
|
||||
public Object clone() {
|
||||
// Since there are no arrays we can just use Object.clone()
|
||||
try {
|
||||
return super.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
Iris.reportError(e);
|
||||
// this shouldn't happen, since we are Cloneable
|
||||
throw new InternalError();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the <i>x</i> coordinate.
|
||||
*
|
||||
* @return the <i>x</i> coordinate.
|
||||
* @since vecmath 1.5
|
||||
*/
|
||||
public final double getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the <i>x</i> coordinate.
|
||||
*
|
||||
* @param x value to <i>x</i> coordinate.
|
||||
* @since vecmath 1.5
|
||||
*/
|
||||
public final void setX(double x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the <i>y</i> coordinate.
|
||||
*
|
||||
* @return the <i>y</i> coordinate.
|
||||
* @since vecmath 1.5
|
||||
*/
|
||||
public final double getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the <i>y</i> coordinate.
|
||||
*
|
||||
* @param y value to <i>y</i> coordinate.
|
||||
* @since vecmath 1.5
|
||||
*/
|
||||
public final void setY(double y) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the <i>z</i> coordinate.
|
||||
*
|
||||
* @return the <i>z</i> coordinate.
|
||||
* @since vecmath 1.5
|
||||
*/
|
||||
public final double getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the <i>z</i> coordinate.
|
||||
*
|
||||
* @param z value to <i>z</i> coordinate.
|
||||
* @since vecmath 1.5
|
||||
*/
|
||||
public final void setZ(double z) {
|
||||
this.z = z;
|
||||
}
|
||||
}
|
||||
655
src/main/java/com/volmit/iris/util/math/Tuple3f.java
Normal file
655
src/main/java/com/volmit/iris/util/math/Tuple3f.java
Normal file
@@ -0,0 +1,655 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.math;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
|
||||
/**
|
||||
* A generic 3-element tuple that is represented by single precision-floating
|
||||
* point x,y,z coordinates.
|
||||
*/
|
||||
public abstract class Tuple3f implements java.io.Serializable, Cloneable {
|
||||
|
||||
static final long serialVersionUID = 5019834619484343712L;
|
||||
|
||||
/**
|
||||
* The x coordinate.
|
||||
*/
|
||||
public float x;
|
||||
|
||||
/**
|
||||
* The y coordinate.
|
||||
*/
|
||||
public float y;
|
||||
|
||||
/**
|
||||
* The z coordinate.
|
||||
*/
|
||||
public float z;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Tuple3f from the specified xyz coordinates.
|
||||
*
|
||||
* @param x the x coordinate
|
||||
* @param y the y coordinate
|
||||
* @param z the z coordinate
|
||||
*/
|
||||
public Tuple3f(float x, float y, float z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Tuple3f from the array of length 3.
|
||||
*
|
||||
* @param t the array of length 3 containing xyz in order
|
||||
*/
|
||||
public Tuple3f(float[] t) {
|
||||
this.x = t[0];
|
||||
this.y = t[1];
|
||||
this.z = t[2];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Tuple3f from the specified Tuple3f.
|
||||
*
|
||||
* @param t1 the Tuple3f containing the initialization x y z data
|
||||
*/
|
||||
public Tuple3f(Tuple3f t1) {
|
||||
this.x = t1.x;
|
||||
this.y = t1.y;
|
||||
this.z = t1.z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Tuple3f from the specified Tuple3d.
|
||||
*
|
||||
* @param t1 the Tuple3d containing the initialization x y z data
|
||||
*/
|
||||
public Tuple3f(Tuple3d t1) {
|
||||
this.x = (float) t1.x;
|
||||
this.y = (float) t1.y;
|
||||
this.z = (float) t1.z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Tuple3f to (0,0,0).
|
||||
*/
|
||||
public Tuple3f() {
|
||||
this.x = 0.0f;
|
||||
this.y = 0.0f;
|
||||
this.z = 0.0f;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string that contains the values of this Tuple3f.
|
||||
* The form is (x,y,z).
|
||||
*
|
||||
* @return the String representation
|
||||
*/
|
||||
public String toString() {
|
||||
return "(" + this.x + ", " + this.y + ", " + this.z + ")";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the specified xyz coordinates.
|
||||
*
|
||||
* @param x the x coordinate
|
||||
* @param y the y coordinate
|
||||
* @param z the z coordinate
|
||||
*/
|
||||
public final void set(float x, float y, float z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the xyz coordinates specified in
|
||||
* the array of length 3.
|
||||
*
|
||||
* @param t the array of length 3 containing xyz in order
|
||||
*/
|
||||
public final void set(float[] t) {
|
||||
this.x = t[0];
|
||||
this.y = t[1];
|
||||
this.z = t[2];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the value of tuple t1.
|
||||
*
|
||||
* @param t1 the tuple to be copied
|
||||
*/
|
||||
public final void set(Tuple3f t1) {
|
||||
this.x = t1.x;
|
||||
this.y = t1.y;
|
||||
this.z = t1.z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the value of tuple t1.
|
||||
*
|
||||
* @param t1 the tuple to be copied
|
||||
*/
|
||||
public final void set(Tuple3d t1) {
|
||||
this.x = (float) t1.x;
|
||||
this.y = (float) t1.y;
|
||||
this.z = (float) t1.z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the value of this tuple and copies the values into t.
|
||||
*
|
||||
* @param t the array of length 3 into which the values are copied
|
||||
*/
|
||||
public final void get(float[] t) {
|
||||
t[0] = this.x;
|
||||
t[1] = this.y;
|
||||
t[2] = this.z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the value of this tuple and copies the values into t.
|
||||
*
|
||||
* @param t the Tuple3f object into which the values of this object are copied
|
||||
*/
|
||||
public final void get(Tuple3f t) {
|
||||
t.x = this.x;
|
||||
t.y = this.y;
|
||||
t.z = this.z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the vector sum of tuples t1 and t2.
|
||||
*
|
||||
* @param t1 the first tuple
|
||||
* @param t2 the second tuple
|
||||
*/
|
||||
public final void add(Tuple3f t1, Tuple3f t2) {
|
||||
this.x = t1.x + t2.x;
|
||||
this.y = t1.y + t2.y;
|
||||
this.z = t1.z + t2.z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the vector sum of itself and tuple t1.
|
||||
*
|
||||
* @param t1 the other tuple
|
||||
*/
|
||||
public final void add(Tuple3f t1) {
|
||||
this.x += t1.x;
|
||||
this.y += t1.y;
|
||||
this.z += t1.z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the vector difference
|
||||
* of tuples t1 and t2 (this = t1 - t2).
|
||||
*
|
||||
* @param t1 the first tuple
|
||||
* @param t2 the second tuple
|
||||
*/
|
||||
public final void sub(Tuple3f t1, Tuple3f t2) {
|
||||
this.x = t1.x - t2.x;
|
||||
this.y = t1.y - t2.y;
|
||||
this.z = t1.z - t2.z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the vector difference of
|
||||
* itself and tuple t1 (this = this - t1) .
|
||||
*
|
||||
* @param t1 the other tuple
|
||||
*/
|
||||
public final void sub(Tuple3f t1) {
|
||||
this.x -= t1.x;
|
||||
this.y -= t1.y;
|
||||
this.z -= t1.z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the negation of tuple t1.
|
||||
*
|
||||
* @param t1 the source tuple
|
||||
*/
|
||||
public final void negate(Tuple3f t1) {
|
||||
this.x = -t1.x;
|
||||
this.y = -t1.y;
|
||||
this.z = -t1.z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Negates the value of this tuple in place.
|
||||
*/
|
||||
public final void negate() {
|
||||
this.x = -this.x;
|
||||
this.y = -this.y;
|
||||
this.z = -this.z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this vector to the scalar multiplication
|
||||
* of tuple t1.
|
||||
*
|
||||
* @param s the scalar value
|
||||
* @param t1 the source tuple
|
||||
*/
|
||||
public final void scale(float s, Tuple3f t1) {
|
||||
this.x = s * t1.x;
|
||||
this.y = s * t1.y;
|
||||
this.z = s * t1.z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the scalar multiplication
|
||||
* of the scale factor with this.
|
||||
*
|
||||
* @param s the scalar value
|
||||
*/
|
||||
public final void scale(float s) {
|
||||
this.x *= s;
|
||||
this.y *= s;
|
||||
this.z *= s;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the scalar multiplication
|
||||
* of tuple t1 and then adds tuple t2 (this = s*t1 + t2).
|
||||
*
|
||||
* @param s the scalar value
|
||||
* @param t1 the tuple to be scaled and added
|
||||
* @param t2 the tuple to be added without a scale
|
||||
*/
|
||||
public final void scaleAdd(float s, Tuple3f t1, Tuple3f t2) {
|
||||
this.x = s * t1.x + t2.x;
|
||||
this.y = s * t1.y + t2.y;
|
||||
this.z = s * t1.z + t2.z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the scalar multiplication
|
||||
* of itself and then adds tuple t1 (this = s*this + t1).
|
||||
*
|
||||
* @param s the scalar value
|
||||
* @param t1 the tuple to be added
|
||||
*/
|
||||
public final void scaleAdd(float s, Tuple3f t1) {
|
||||
this.x = s * this.x + t1.x;
|
||||
this.y = s * this.y + t1.y;
|
||||
this.z = s * this.z + t1.z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the Object t1 is of type Tuple3f and all of the
|
||||
* data members of t1 are equal to the corresponding data members in
|
||||
* this Tuple3f.
|
||||
*
|
||||
* @param t1 the vector with which the comparison is made
|
||||
* @return true or false
|
||||
*/
|
||||
public boolean equals(Tuple3f t1) {
|
||||
try {
|
||||
return (this.x == t1.x && this.y == t1.y && this.z == t1.z);
|
||||
} catch (NullPointerException e2) {
|
||||
Iris.reportError(e2);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the Object t1 is of type Tuple3f and all of the
|
||||
* data members of t1 are equal to the corresponding data members in
|
||||
* this Tuple3f.
|
||||
*
|
||||
* @param t1 the Object with which the comparison is made
|
||||
* @return true or false
|
||||
*/
|
||||
public boolean equals(Object t1) {
|
||||
try {
|
||||
Tuple3f t2 = (Tuple3f) t1;
|
||||
return (this.x == t2.x && this.y == t2.y && this.z == t2.z);
|
||||
} catch (NullPointerException | ClassCastException e2) {
|
||||
Iris.reportError(e2);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the L-infinite distance between this tuple
|
||||
* and tuple t1 is less than or equal to the epsilon parameter,
|
||||
* otherwise returns false. The L-infinite
|
||||
* distance is equal to MAX[abs(x1-x2), abs(y1-y2), abs(z1-z2)].
|
||||
*
|
||||
* @param t1 the tuple to be compared to this tuple
|
||||
* @param epsilon the threshold value
|
||||
* @return true or false
|
||||
*/
|
||||
public boolean epsilonEquals(Tuple3f t1, float epsilon) {
|
||||
float diff;
|
||||
|
||||
diff = x - t1.x;
|
||||
if (Float.isNaN(diff)) return false;
|
||||
if ((diff < 0 ? -diff : diff) > epsilon) return false;
|
||||
|
||||
diff = y - t1.y;
|
||||
if (Float.isNaN(diff)) return false;
|
||||
if ((diff < 0 ? -diff : diff) > epsilon) return false;
|
||||
|
||||
diff = z - t1.z;
|
||||
if (Float.isNaN(diff)) return false;
|
||||
return !((diff < 0 ? -diff : diff) > epsilon);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a hash code value based on the data values in this
|
||||
* object. Two different Tuple3f objects with identical data values
|
||||
* (i.e., Tuple3f.equals returns true) will return the same hash
|
||||
* code value. Two objects with different data members may return the
|
||||
* same hash value, although this is not likely.
|
||||
*
|
||||
* @return the integer hash code value
|
||||
*/
|
||||
public int hashCode() {
|
||||
long bits = 1L;
|
||||
bits = 31L * bits + (long) VecMathUtil.floatToIntBits(x);
|
||||
bits = 31L * bits + (long) VecMathUtil.floatToIntBits(y);
|
||||
bits = 31L * bits + (long) VecMathUtil.floatToIntBits(z);
|
||||
return (int) (bits ^ (bits >> 32));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clamps the tuple parameter to the range [low, high] and
|
||||
* places the values into this tuple.
|
||||
*
|
||||
* @param min the lowest value in the tuple after clamping
|
||||
* @param max the highest value in the tuple after clamping
|
||||
* @param t the source tuple, which will not be modified
|
||||
*/
|
||||
public final void clamp(float min, float max, Tuple3f t) {
|
||||
if (t.x > max) {
|
||||
x = max;
|
||||
} else x = Math.max(t.x, min);
|
||||
|
||||
if (t.y > max) {
|
||||
y = max;
|
||||
} else y = Math.max(t.y, min);
|
||||
|
||||
if (t.z > max) {
|
||||
z = max;
|
||||
} else z = Math.max(t.z, min);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clamps the minimum value of the tuple parameter to the min
|
||||
* parameter and places the values into this tuple.
|
||||
*
|
||||
* @param min the lowest value in the tuple after clamping
|
||||
* @param t the source tuple, which will not be modified
|
||||
*/
|
||||
public final void clampMin(float min, Tuple3f t) {
|
||||
x = Math.max(t.x, min);
|
||||
|
||||
y = Math.max(t.y, min);
|
||||
|
||||
z = Math.max(t.z, min);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clamps the maximum value of the tuple parameter to the max
|
||||
* parameter and places the values into this tuple.
|
||||
*
|
||||
* @param max the highest value in the tuple after clamping
|
||||
* @param t the source tuple, which will not be modified
|
||||
*/
|
||||
public final void clampMax(float max, Tuple3f t) {
|
||||
x = Math.min(t.x, max);
|
||||
|
||||
y = Math.min(t.y, max);
|
||||
|
||||
z = Math.min(t.z, max);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets each component of the tuple parameter to its absolute
|
||||
* value and places the modified values into this tuple.
|
||||
*
|
||||
* @param t the source tuple, which will not be modified
|
||||
*/
|
||||
public final void absolute(Tuple3f t) {
|
||||
x = Math.abs(t.x);
|
||||
y = Math.abs(t.y);
|
||||
z = Math.abs(t.z);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clamps this tuple to the range [low, high].
|
||||
*
|
||||
* @param min the lowest value in this tuple after clamping
|
||||
* @param max the highest value in this tuple after clamping
|
||||
*/
|
||||
public final void clamp(float min, float max) {
|
||||
if (x > max) {
|
||||
x = max;
|
||||
} else if (x < min) {
|
||||
x = min;
|
||||
}
|
||||
|
||||
if (y > max) {
|
||||
y = max;
|
||||
} else if (y < min) {
|
||||
y = min;
|
||||
}
|
||||
|
||||
if (z > max) {
|
||||
z = max;
|
||||
} else if (z < min) {
|
||||
z = min;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clamps the minimum value of this tuple to the min parameter.
|
||||
*
|
||||
* @param min the lowest value in this tuple after clamping
|
||||
*/
|
||||
public final void clampMin(float min) {
|
||||
if (x < min) x = min;
|
||||
if (y < min) y = min;
|
||||
if (z < min) z = min;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clamps the maximum value of this tuple to the max parameter.
|
||||
*
|
||||
* @param max the highest value in the tuple after clamping
|
||||
*/
|
||||
public final void clampMax(float max) {
|
||||
if (x > max) x = max;
|
||||
if (y > max) y = max;
|
||||
if (z > max) z = max;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets each component of this tuple to its absolute value.
|
||||
*/
|
||||
public final void absolute() {
|
||||
x = Math.abs(x);
|
||||
y = Math.abs(y);
|
||||
z = Math.abs(z);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Linearly interpolates between tuples t1 and t2 and places the
|
||||
* result into this tuple: this = (1-alpha)*t1 + alpha*t2.
|
||||
*
|
||||
* @param t1 the first tuple
|
||||
* @param t2 the second tuple
|
||||
* @param alpha the alpha interpolation parameter
|
||||
*/
|
||||
public final void interpolate(Tuple3f t1, Tuple3f t2, float alpha) {
|
||||
this.x = (1 - alpha) * t1.x + alpha * t2.x;
|
||||
this.y = (1 - alpha) * t1.y + alpha * t2.y;
|
||||
this.z = (1 - alpha) * t1.z + alpha * t2.z;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Linearly interpolates between this tuple and tuple t1 and
|
||||
* places the result into this tuple: this = (1-alpha)*this + alpha*t1.
|
||||
*
|
||||
* @param t1 the first tuple
|
||||
* @param alpha the alpha interpolation parameter
|
||||
*/
|
||||
public final void interpolate(Tuple3f t1, float alpha) {
|
||||
this.x = (1 - alpha) * this.x + alpha * t1.x;
|
||||
this.y = (1 - alpha) * this.y + alpha * t1.y;
|
||||
this.z = (1 - alpha) * this.z + alpha * t1.z;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new object of the same class as this object.
|
||||
*
|
||||
* @return a clone of this instance.
|
||||
* @throws OutOfMemoryError if there is not enough memory.
|
||||
* @see java.lang.Cloneable
|
||||
* @since vecmath 1.3
|
||||
*/
|
||||
public Object clone() {
|
||||
// Since there are no arrays we can just use Object.clone()
|
||||
try {
|
||||
return super.clone();
|
||||
} catch (CloneNotSupportedException e) {Iris.reportError(e);
|
||||
// this shouldn't happen, since we are Cloneable
|
||||
throw new InternalError();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the <i>x</i> coordinate.
|
||||
*
|
||||
* @return the <i>x</i> coordinate.
|
||||
* @since vecmath 1.5
|
||||
*/
|
||||
public final float getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the <i>x</i> coordinate.
|
||||
*
|
||||
* @param x value to <i>x</i> coordinate.
|
||||
* @since vecmath 1.5
|
||||
*/
|
||||
public final void setX(float x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the <i>y</i> coordinate.
|
||||
*
|
||||
* @return the <i>y</i> coordinate.
|
||||
* @since vecmath 1.5
|
||||
*/
|
||||
public final float getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the <i>y</i> coordinate.
|
||||
*
|
||||
* @param y value to <i>y</i> coordinate.
|
||||
* @since vecmath 1.5
|
||||
*/
|
||||
public final void setY(float y) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the <i>z</i> coordinate.
|
||||
*
|
||||
* @return the <i>z</i> coordinate
|
||||
* @since vecmath 1.5
|
||||
*/
|
||||
public final float getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the <i>Z</i> coordinate.
|
||||
*
|
||||
* @param z value to <i>z</i> coordinate.
|
||||
* @since vecmath 1.5
|
||||
*/
|
||||
public final void setZ(float z) {
|
||||
this.z = z;
|
||||
}
|
||||
}
|
||||
807
src/main/java/com/volmit/iris/util/math/Tuple4d.java
Normal file
807
src/main/java/com/volmit/iris/util/math/Tuple4d.java
Normal file
@@ -0,0 +1,807 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.math;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
|
||||
/**
|
||||
* A 4 element tuple represented by double precision floating point
|
||||
* x,y,z,w coordinates.
|
||||
*/
|
||||
public abstract class Tuple4d implements java.io.Serializable, Cloneable {
|
||||
|
||||
static final long serialVersionUID = -4748953690425311052L;
|
||||
|
||||
/**
|
||||
* The x coordinate.
|
||||
*/
|
||||
public double x;
|
||||
|
||||
/**
|
||||
* The y coordinate.
|
||||
*/
|
||||
public double y;
|
||||
|
||||
/**
|
||||
* The z coordinate.
|
||||
*/
|
||||
public double z;
|
||||
|
||||
/**
|
||||
* The w coordinate.
|
||||
*/
|
||||
public double w;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Tuple4d from the specified xyzw coordinates.
|
||||
*
|
||||
* @param x the x coordinate
|
||||
* @param y the y coordinate
|
||||
* @param z the z coordinate
|
||||
* @param w the w coordinate
|
||||
*/
|
||||
public Tuple4d(double x, double y, double z, double w) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.w = w;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Tuple4d from the coordinates contained
|
||||
* in the array.
|
||||
*
|
||||
* @param t the array of length 4 containing xyzw in order
|
||||
*/
|
||||
public Tuple4d(double[] t) {
|
||||
this.x = t[0];
|
||||
this.y = t[1];
|
||||
this.z = t[2];
|
||||
this.w = t[3];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Tuple4d from the specified Tuple4d.
|
||||
*
|
||||
* @param t1 the Tuple4d containing the initialization x y z w data
|
||||
*/
|
||||
public Tuple4d(Tuple4d t1) {
|
||||
this.x = t1.x;
|
||||
this.y = t1.y;
|
||||
this.z = t1.z;
|
||||
this.w = t1.w;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Tuple4d from the specified Tuple4f.
|
||||
*
|
||||
* @param t1 the Tuple4f containing the initialization x y z w data
|
||||
*/
|
||||
public Tuple4d(Tuple4f t1) {
|
||||
this.x = t1.x;
|
||||
this.y = t1.y;
|
||||
this.z = t1.z;
|
||||
this.w = t1.w;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Tuple4d to (0,0,0,0).
|
||||
*/
|
||||
public Tuple4d() {
|
||||
this.x = 0.0;
|
||||
this.y = 0.0;
|
||||
this.z = 0.0;
|
||||
this.w = 0.0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the specified xyzw coordinates.
|
||||
*
|
||||
* @param x the x coordinate
|
||||
* @param y the y coordinate
|
||||
* @param z the z coordinate
|
||||
* @param w the w coordinate
|
||||
*/
|
||||
public final void set(double x, double y, double z, double w) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.w = w;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the specified xyzw coordinates.
|
||||
*
|
||||
* @param t the array of length 4 containing xyzw in order
|
||||
*/
|
||||
public final void set(double[] t) {
|
||||
this.x = t[0];
|
||||
this.y = t[1];
|
||||
this.z = t[2];
|
||||
this.w = t[3];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the value of tuple t1.
|
||||
*
|
||||
* @param t1 the tuple to be copied
|
||||
*/
|
||||
public final void set(Tuple4d t1) {
|
||||
this.x = t1.x;
|
||||
this.y = t1.y;
|
||||
this.z = t1.z;
|
||||
this.w = t1.w;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the value of tuple t1.
|
||||
*
|
||||
* @param t1 the tuple to be copied
|
||||
*/
|
||||
public final void set(Tuple4f t1) {
|
||||
this.x = t1.x;
|
||||
this.y = t1.y;
|
||||
this.z = t1.z;
|
||||
this.w = t1.w;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the value of this tuple and places it into the array t of
|
||||
* length four in x,y,z,w order.
|
||||
*
|
||||
* @param t the array of length four
|
||||
*/
|
||||
public final void get(double[] t) {
|
||||
t[0] = this.x;
|
||||
t[1] = this.y;
|
||||
t[2] = this.z;
|
||||
t[3] = this.w;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the value of this tuple and places it into the Tuple4d
|
||||
* argument of
|
||||
* length four in x,y,z,w order.
|
||||
*
|
||||
* @param t the Tuple into which the values will be copied
|
||||
*/
|
||||
public final void get(Tuple4d t) {
|
||||
t.x = this.x;
|
||||
t.y = this.y;
|
||||
t.z = this.z;
|
||||
t.w = this.w;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the tuple sum of tuples t1 and t2.
|
||||
*
|
||||
* @param t1 the first tuple
|
||||
* @param t2 the second tuple
|
||||
*/
|
||||
public final void add(Tuple4d t1, Tuple4d t2) {
|
||||
this.x = t1.x + t2.x;
|
||||
this.y = t1.y + t2.y;
|
||||
this.z = t1.z + t2.z;
|
||||
this.w = t1.w + t2.w;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the sum of itself and tuple t1.
|
||||
*
|
||||
* @param t1 the other tuple
|
||||
*/
|
||||
public final void add(Tuple4d t1) {
|
||||
this.x += t1.x;
|
||||
this.y += t1.y;
|
||||
this.z += t1.z;
|
||||
this.w += t1.w;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the difference
|
||||
* of tuples t1 and t2 (this = t1 - t2).
|
||||
*
|
||||
* @param t1 the first tuple
|
||||
* @param t2 the second tuple
|
||||
*/
|
||||
public final void sub(Tuple4d t1, Tuple4d t2) {
|
||||
this.x = t1.x - t2.x;
|
||||
this.y = t1.y - t2.y;
|
||||
this.z = t1.z - t2.z;
|
||||
this.w = t1.w - t2.w;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the difference of itself
|
||||
* and tuple t1 (this = this - t1).
|
||||
*
|
||||
* @param t1 the other tuple
|
||||
*/
|
||||
public final void sub(Tuple4d t1) {
|
||||
this.x -= t1.x;
|
||||
this.y -= t1.y;
|
||||
this.z -= t1.z;
|
||||
this.w -= t1.w;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the negation of tuple t1.
|
||||
*
|
||||
* @param t1 the source tuple
|
||||
*/
|
||||
public final void negate(Tuple4d t1) {
|
||||
this.x = -t1.x;
|
||||
this.y = -t1.y;
|
||||
this.z = -t1.z;
|
||||
this.w = -t1.w;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Negates the value of this tuple in place.
|
||||
*/
|
||||
public final void negate() {
|
||||
this.x = -this.x;
|
||||
this.y = -this.y;
|
||||
this.z = -this.z;
|
||||
this.w = -this.w;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the scalar multiplication
|
||||
* of the scale factor with the tuple t1.
|
||||
*
|
||||
* @param s the scalar value
|
||||
* @param t1 the source tuple
|
||||
*/
|
||||
public final void scale(double s, Tuple4d t1) {
|
||||
this.x = s * t1.x;
|
||||
this.y = s * t1.y;
|
||||
this.z = s * t1.z;
|
||||
this.w = s * t1.w;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the scalar multiplication
|
||||
* of the scale factor with this.
|
||||
*
|
||||
* @param s the scalar value
|
||||
*/
|
||||
public final void scale(double s) {
|
||||
this.x *= s;
|
||||
this.y *= s;
|
||||
this.z *= s;
|
||||
this.w *= s;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the scalar multiplication by s
|
||||
* of tuple t1 plus tuple t2 (this = s*t1 + t2).
|
||||
*
|
||||
* @param s the scalar value
|
||||
* @param t1 the tuple to be multipled
|
||||
* @param t2 the tuple to be added
|
||||
*/
|
||||
public final void scaleAdd(double s, Tuple4d t1, Tuple4d t2) {
|
||||
this.x = s * t1.x + t2.x;
|
||||
this.y = s * t1.y + t2.y;
|
||||
this.z = s * t1.z + t2.z;
|
||||
this.w = s * t1.w + t2.w;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated Use scaleAdd(double,Tuple4d) instead
|
||||
*/
|
||||
public final void scaleAdd(float s, Tuple4d t1) {
|
||||
scaleAdd((double) s, t1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the scalar multiplication
|
||||
* of itself and then adds tuple t1 (this = s*this + t1).
|
||||
*
|
||||
* @param s the scalar value
|
||||
* @param t1 the tuple to be added
|
||||
*/
|
||||
public final void scaleAdd(double s, Tuple4d t1) {
|
||||
this.x = s * this.x + t1.x;
|
||||
this.y = s * this.y + t1.y;
|
||||
this.z = s * this.z + t1.z;
|
||||
this.w = s * this.w + t1.w;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string that contains the values of this Tuple4d.
|
||||
* The form is (x,y,z,w).
|
||||
*
|
||||
* @return the String representation
|
||||
*/
|
||||
public String toString() {
|
||||
return "(" + this.x + ", " + this.y + ", " + this.z + ", " + this.w + ")";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if all of the data members of Tuple4d t1 are
|
||||
* equal to the corresponding data members in this Tuple4d.
|
||||
*
|
||||
* @param t1 the tuple with which the comparison is made
|
||||
* @return true or false
|
||||
*/
|
||||
public boolean equals(Tuple4d t1) {
|
||||
try {
|
||||
return (this.x == t1.x && this.y == t1.y && this.z == t1.z
|
||||
&& this.w == t1.w);
|
||||
} catch (NullPointerException e2) {
|
||||
Iris.reportError(e2);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the Object t1 is of type Tuple4d and all of the
|
||||
* data members of t1 are equal to the corresponding data members in
|
||||
* this Tuple4d.
|
||||
*
|
||||
* @param t1 the object with which the comparison is made
|
||||
* @return true or false
|
||||
*/
|
||||
public boolean equals(Object t1) {
|
||||
try {
|
||||
|
||||
Tuple4d t2 = (Tuple4d) t1;
|
||||
return (this.x == t2.x && this.y == t2.y &&
|
||||
this.z == t2.z && this.w == t2.w);
|
||||
} catch (NullPointerException | ClassCastException e2) {
|
||||
Iris.reportError(e2);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the L-infinite distance between this tuple
|
||||
* and tuple t1 is less than or equal to the epsilon parameter,
|
||||
* otherwise returns false. The L-infinite
|
||||
* distance is equal to
|
||||
* MAX[abs(x1-x2), abs(y1-y2), abs(z1-z2), abs(w1-w2)].
|
||||
*
|
||||
* @param t1 the tuple to be compared to this tuple
|
||||
* @param epsilon the threshold value
|
||||
* @return true or false
|
||||
*/
|
||||
public boolean epsilonEquals(Tuple4d t1, double epsilon) {
|
||||
double diff;
|
||||
|
||||
diff = x - t1.x;
|
||||
if (Double.isNaN(diff)) return false;
|
||||
if ((diff < 0 ? -diff : diff) > epsilon) return false;
|
||||
|
||||
diff = y - t1.y;
|
||||
if (Double.isNaN(diff)) return false;
|
||||
if ((diff < 0 ? -diff : diff) > epsilon) return false;
|
||||
|
||||
diff = z - t1.z;
|
||||
if (Double.isNaN(diff)) return false;
|
||||
if ((diff < 0 ? -diff : diff) > epsilon) return false;
|
||||
|
||||
diff = w - t1.w;
|
||||
if (Double.isNaN(diff)) return false;
|
||||
return !((diff < 0 ? -diff : diff) > epsilon);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a hash code value based on the data values in this
|
||||
* object. Two different Tuple4d objects with identical data values
|
||||
* (i.e., Tuple4d.equals returns true) will return the same hash
|
||||
* code value. Two objects with different data members may return the
|
||||
* same hash value, although this is not likely.
|
||||
*
|
||||
* @return the integer hash code value
|
||||
*/
|
||||
public int hashCode() {
|
||||
long bits = 1L;
|
||||
bits = 31L * bits + VecMathUtil.doubleToLongBits(x);
|
||||
bits = 31L * bits + VecMathUtil.doubleToLongBits(y);
|
||||
bits = 31L * bits + VecMathUtil.doubleToLongBits(z);
|
||||
bits = 31L * bits + VecMathUtil.doubleToLongBits(w);
|
||||
return (int) (bits ^ (bits >> 32));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated Use clamp(double,double,Tuple4d) instead
|
||||
*/
|
||||
public final void clamp(float min, float max, Tuple4d t) {
|
||||
clamp(min, (double) max, t);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clamps the tuple parameter to the range [low, high] and
|
||||
* places the values into this tuple.
|
||||
*
|
||||
* @param min the lowest value in the tuple after clamping
|
||||
* @param max the highest value in the tuple after clamping
|
||||
* @param t the source tuple, which will not be modified
|
||||
*/
|
||||
public final void clamp(double min, double max, Tuple4d t) {
|
||||
if (t.x > max) {
|
||||
x = max;
|
||||
} else x = Math.max(t.x, min);
|
||||
|
||||
if (t.y > max) {
|
||||
y = max;
|
||||
} else y = Math.max(t.y, min);
|
||||
|
||||
if (t.z > max) {
|
||||
z = max;
|
||||
} else z = Math.max(t.z, min);
|
||||
|
||||
if (t.w > max) {
|
||||
w = max;
|
||||
} else w = Math.max(t.w, min);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated Use clampMin(double,Tuple4d) instead
|
||||
*/
|
||||
public final void clampMin(float min, Tuple4d t) {
|
||||
clampMin((double) min, t);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clamps the minimum value of the tuple parameter to the min
|
||||
* parameter and places the values into this tuple.
|
||||
*
|
||||
* @param min the lowest value in the tuple after clamping
|
||||
* @param t the source tuple, which will not be modified
|
||||
*/
|
||||
public final void clampMin(double min, Tuple4d t) {
|
||||
x = Math.max(t.x, min);
|
||||
|
||||
y = Math.max(t.y, min);
|
||||
|
||||
z = Math.max(t.z, min);
|
||||
|
||||
w = Math.max(t.w, min);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated Use clampMax(double,Tuple4d) instead
|
||||
*/
|
||||
public final void clampMax(float max, Tuple4d t) {
|
||||
clampMax((double) max, t);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clamps the maximum value of the tuple parameter to the max
|
||||
* parameter and places the values into this tuple.
|
||||
*
|
||||
* @param max the highest value in the tuple after clamping
|
||||
* @param t the source tuple, which will not be modified
|
||||
*/
|
||||
public final void clampMax(double max, Tuple4d t) {
|
||||
x = Math.min(t.x, max);
|
||||
|
||||
y = Math.min(t.y, max);
|
||||
|
||||
z = Math.min(t.z, max);
|
||||
|
||||
if (t.w > max) {
|
||||
w = max;
|
||||
} else {
|
||||
w = t.z;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets each component of the tuple parameter to its absolute
|
||||
* value and places the modified values into this tuple.
|
||||
*
|
||||
* @param t the source tuple, which will not be modified
|
||||
*/
|
||||
public final void absolute(Tuple4d t) {
|
||||
x = Math.abs(t.x);
|
||||
y = Math.abs(t.y);
|
||||
z = Math.abs(t.z);
|
||||
w = Math.abs(t.w);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated Use clamp(double,double) instead
|
||||
*/
|
||||
public final void clamp(float min, float max) {
|
||||
clamp(min, (double) max);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clamps this tuple to the range [low, high].
|
||||
*
|
||||
* @param min the lowest value in this tuple after clamping
|
||||
* @param max the highest value in this tuple after clamping
|
||||
*/
|
||||
public final void clamp(double min, double max) {
|
||||
if (x > max) {
|
||||
x = max;
|
||||
} else if (x < min) {
|
||||
x = min;
|
||||
}
|
||||
|
||||
if (y > max) {
|
||||
y = max;
|
||||
} else if (y < min) {
|
||||
y = min;
|
||||
}
|
||||
|
||||
if (z > max) {
|
||||
z = max;
|
||||
} else if (z < min) {
|
||||
z = min;
|
||||
}
|
||||
|
||||
if (w > max) {
|
||||
w = max;
|
||||
} else if (w < min) {
|
||||
w = min;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated Use clampMin(double) instead
|
||||
*/
|
||||
public final void clampMin(float min) {
|
||||
clampMin((double) min);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clamps the minimum value of this tuple to the min parameter.
|
||||
*
|
||||
* @param min the lowest value in this tuple after clamping
|
||||
*/
|
||||
public final void clampMin(double min) {
|
||||
if (x < min) x = min;
|
||||
if (y < min) y = min;
|
||||
if (z < min) z = min;
|
||||
if (w < min) w = min;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated Use clampMax(double) instead
|
||||
*/
|
||||
public final void clampMax(float max) {
|
||||
clampMax((double) max);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clamps the maximum value of this tuple to the max parameter.
|
||||
*
|
||||
* @param max the highest value in the tuple after clamping
|
||||
*/
|
||||
public final void clampMax(double max) {
|
||||
if (x > max) x = max;
|
||||
if (y > max) y = max;
|
||||
if (z > max) z = max;
|
||||
if (w > max) w = max;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets each component of this tuple to its absolute value.
|
||||
*/
|
||||
public final void absolute() {
|
||||
x = Math.abs(x);
|
||||
y = Math.abs(y);
|
||||
z = Math.abs(z);
|
||||
w = Math.abs(w);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated Use interpolate(Tuple4d,Tuple4d,double) instead
|
||||
*/
|
||||
public void interpolate(Tuple4d t1, Tuple4d t2, float alpha) {
|
||||
interpolate(t1, t2, (double) alpha);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Linearly interpolates between tuples t1 and t2 and places the
|
||||
* result into this tuple: this = (1-alpha)*t1 + alpha*t2.
|
||||
*
|
||||
* @param t1 the first tuple
|
||||
* @param t2 the second tuple
|
||||
* @param alpha the alpha interpolation parameter
|
||||
*/
|
||||
public void interpolate(Tuple4d t1, Tuple4d t2, double alpha) {
|
||||
this.x = (1 - alpha) * t1.x + alpha * t2.x;
|
||||
this.y = (1 - alpha) * t1.y + alpha * t2.y;
|
||||
this.z = (1 - alpha) * t1.z + alpha * t2.z;
|
||||
this.w = (1 - alpha) * t1.w + alpha * t2.w;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated Use interpolate(Tuple4d,double) instead
|
||||
*/
|
||||
public void interpolate(Tuple4d t1, float alpha) {
|
||||
interpolate(t1, (double) alpha);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Linearly interpolates between this tuple and tuple t1 and
|
||||
* places the result into this tuple: this = (1-alpha)*this + alpha*t1.
|
||||
*
|
||||
* @param t1 the first tuple
|
||||
* @param alpha the alpha interpolation parameter
|
||||
*/
|
||||
public void interpolate(Tuple4d t1, double alpha) {
|
||||
this.x = (1 - alpha) * this.x + alpha * t1.x;
|
||||
this.y = (1 - alpha) * this.y + alpha * t1.y;
|
||||
this.z = (1 - alpha) * this.z + alpha * t1.z;
|
||||
this.w = (1 - alpha) * this.w + alpha * t1.w;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new object of the same class as this object.
|
||||
*
|
||||
* @return a clone of this instance.
|
||||
* @throws OutOfMemoryError if there is not enough memory.
|
||||
* @see java.lang.Cloneable
|
||||
* @since vecmath 1.3
|
||||
*/
|
||||
public Object clone() {
|
||||
// Since there are no arrays we can just use Object.clone()
|
||||
try {
|
||||
return super.clone();
|
||||
} catch (CloneNotSupportedException e) {Iris.reportError(e);
|
||||
// this shouldn't happen, since we are Cloneable
|
||||
throw new InternalError();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the <i>x</i> coordinate.
|
||||
*
|
||||
* @return the x coordinate.
|
||||
* @since vecmath 1.5
|
||||
*/
|
||||
public final double getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the <i>x</i> coordinate.
|
||||
*
|
||||
* @param x value to <i>x</i> coordinate.
|
||||
* @since vecmath 1.5
|
||||
*/
|
||||
public final void setX(double x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the <i>y</i> coordinate.
|
||||
*
|
||||
* @return the <i>y</i> coordinate.
|
||||
* @since vecmath 1.5
|
||||
*/
|
||||
public final double getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the <i>y</i> coordinate.
|
||||
*
|
||||
* @param y value to <i>y</i> coordinate.
|
||||
* @since vecmath 1.5
|
||||
*/
|
||||
public final void setY(double y) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the <i>z</i> coordinate.
|
||||
*
|
||||
* @return the <i>z</i> coordinate.
|
||||
* @since vecmath 1.5
|
||||
*/
|
||||
public final double getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the <i>z</i> coordinate.
|
||||
*
|
||||
* @param z value to <i>z</i> coordinate.
|
||||
* @since vecmath 1.5
|
||||
*/
|
||||
public final void setZ(double z) {
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the <i>w</i> coordinate.
|
||||
*
|
||||
* @return the <i>w</i> coordinate.
|
||||
* @since vecmath 1.5
|
||||
*/
|
||||
public final double getW() {
|
||||
return w;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the <i>w</i> coordinate.
|
||||
*
|
||||
* @param w value to <i>w</i> coordinate.
|
||||
* @since vecmath 1.5
|
||||
*/
|
||||
public final void setW(double w) {
|
||||
this.w = w;
|
||||
}
|
||||
}
|
||||
731
src/main/java/com/volmit/iris/util/math/Tuple4f.java
Normal file
731
src/main/java/com/volmit/iris/util/math/Tuple4f.java
Normal file
@@ -0,0 +1,731 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.math;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
|
||||
/**
|
||||
* A 4-element tuple represented by single-precision floating point x,y,z,w
|
||||
* coordinates.
|
||||
*/
|
||||
public abstract class Tuple4f implements java.io.Serializable, Cloneable {
|
||||
|
||||
static final long serialVersionUID = 7068460319248845763L;
|
||||
|
||||
/**
|
||||
* The x coordinate.
|
||||
*/
|
||||
public float x;
|
||||
|
||||
/**
|
||||
* The y coordinate.
|
||||
*/
|
||||
public float y;
|
||||
|
||||
/**
|
||||
* The z coordinate.
|
||||
*/
|
||||
public float z;
|
||||
|
||||
/**
|
||||
* The w coordinate.
|
||||
*/
|
||||
public float w;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Tuple4f from the specified xyzw coordinates.
|
||||
*
|
||||
* @param x the x coordinate
|
||||
* @param y the y coordinate
|
||||
* @param z the z coordinate
|
||||
* @param w the w coordinate
|
||||
*/
|
||||
public Tuple4f(float x, float y, float z, float w) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.w = w;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Tuple4f from the array of length 4.
|
||||
*
|
||||
* @param t the array of length 4 containing xyzw in order
|
||||
*/
|
||||
public Tuple4f(float[] t) {
|
||||
this.x = t[0];
|
||||
this.y = t[1];
|
||||
this.z = t[2];
|
||||
this.w = t[3];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Tuple4f from the specified Tuple4f.
|
||||
*
|
||||
* @param t1 the Tuple4f containing the initialization x y z w data
|
||||
*/
|
||||
public Tuple4f(Tuple4f t1) {
|
||||
this.x = t1.x;
|
||||
this.y = t1.y;
|
||||
this.z = t1.z;
|
||||
this.w = t1.w;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Tuple4f from the specified Tuple4d.
|
||||
*
|
||||
* @param t1 the Tuple4d containing the initialization x y z w data
|
||||
*/
|
||||
public Tuple4f(Tuple4d t1) {
|
||||
this.x = (float) t1.x;
|
||||
this.y = (float) t1.y;
|
||||
this.z = (float) t1.z;
|
||||
this.w = (float) t1.w;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Tuple4f to (0,0,0,0).
|
||||
*/
|
||||
public Tuple4f() {
|
||||
this.x = 0.0f;
|
||||
this.y = 0.0f;
|
||||
this.z = 0.0f;
|
||||
this.w = 0.0f;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the specified xyzw coordinates.
|
||||
*
|
||||
* @param x the x coordinate
|
||||
* @param y the y coordinate
|
||||
* @param z the z coordinate
|
||||
* @param w the w coordinate
|
||||
*/
|
||||
public final void set(float x, float y, float z, float w) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.w = w;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the specified coordinates in the
|
||||
* array of length 4.
|
||||
*
|
||||
* @param t the array of length 4 containing xyzw in order
|
||||
*/
|
||||
public final void set(float[] t) {
|
||||
this.x = t[0];
|
||||
this.y = t[1];
|
||||
this.z = t[2];
|
||||
this.w = t[3];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the value of tuple t1.
|
||||
*
|
||||
* @param t1 the tuple to be copied
|
||||
*/
|
||||
public final void set(Tuple4f t1) {
|
||||
this.x = t1.x;
|
||||
this.y = t1.y;
|
||||
this.z = t1.z;
|
||||
this.w = t1.w;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the value of tuple t1.
|
||||
*
|
||||
* @param t1 the tuple to be copied
|
||||
*/
|
||||
public final void set(Tuple4d t1) {
|
||||
this.x = (float) t1.x;
|
||||
this.y = (float) t1.y;
|
||||
this.z = (float) t1.z;
|
||||
this.w = (float) t1.w;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copies the values of this tuple into the array t.
|
||||
*
|
||||
* @param t the array
|
||||
*/
|
||||
public final void get(float[] t) {
|
||||
t[0] = this.x;
|
||||
t[1] = this.y;
|
||||
t[2] = this.z;
|
||||
t[3] = this.w;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copies the values of this tuple into the tuple t.
|
||||
*
|
||||
* @param t the target tuple
|
||||
*/
|
||||
public final void get(Tuple4f t) {
|
||||
t.x = this.x;
|
||||
t.y = this.y;
|
||||
t.z = this.z;
|
||||
t.w = this.w;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the sum of tuples t1 and t2.
|
||||
*
|
||||
* @param t1 the first tuple
|
||||
* @param t2 the second tuple
|
||||
*/
|
||||
public final void add(Tuple4f t1, Tuple4f t2) {
|
||||
this.x = t1.x + t2.x;
|
||||
this.y = t1.y + t2.y;
|
||||
this.z = t1.z + t2.z;
|
||||
this.w = t1.w + t2.w;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the sum of itself and t1.
|
||||
*
|
||||
* @param t1 the other tuple
|
||||
*/
|
||||
public final void add(Tuple4f t1) {
|
||||
this.x += t1.x;
|
||||
this.y += t1.y;
|
||||
this.z += t1.z;
|
||||
this.w += t1.w;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the difference
|
||||
* of tuples t1 and t2 (this = t1 - t2).
|
||||
*
|
||||
* @param t1 the first tuple
|
||||
* @param t2 the second tuple
|
||||
*/
|
||||
public final void sub(Tuple4f t1, Tuple4f t2) {
|
||||
this.x = t1.x - t2.x;
|
||||
this.y = t1.y - t2.y;
|
||||
this.z = t1.z - t2.z;
|
||||
this.w = t1.w - t2.w;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the difference
|
||||
* of itself and t1 (this = this - t1).
|
||||
*
|
||||
* @param t1 the other tuple
|
||||
*/
|
||||
public final void sub(Tuple4f t1) {
|
||||
this.x -= t1.x;
|
||||
this.y -= t1.y;
|
||||
this.z -= t1.z;
|
||||
this.w -= t1.w;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the negation of tuple t1.
|
||||
*
|
||||
* @param t1 the source tuple
|
||||
*/
|
||||
public final void negate(Tuple4f t1) {
|
||||
this.x = -t1.x;
|
||||
this.y = -t1.y;
|
||||
this.z = -t1.z;
|
||||
this.w = -t1.w;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Negates the value of this tuple in place.
|
||||
*/
|
||||
public final void negate() {
|
||||
this.x = -this.x;
|
||||
this.y = -this.y;
|
||||
this.z = -this.z;
|
||||
this.w = -this.w;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the scalar multiplication
|
||||
* of tuple t1.
|
||||
*
|
||||
* @param s the scalar value
|
||||
* @param t1 the source tuple
|
||||
*/
|
||||
public final void scale(float s, Tuple4f t1) {
|
||||
this.x = s * t1.x;
|
||||
this.y = s * t1.y;
|
||||
this.z = s * t1.z;
|
||||
this.w = s * t1.w;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the scalar multiplication
|
||||
* of the scale factor with this.
|
||||
*
|
||||
* @param s the scalar value
|
||||
*/
|
||||
public final void scale(float s) {
|
||||
this.x *= s;
|
||||
this.y *= s;
|
||||
this.z *= s;
|
||||
this.w *= s;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the scalar multiplication
|
||||
* of tuple t1 plus tuple t2 (this = s*t1 + t2).
|
||||
*
|
||||
* @param s the scalar value
|
||||
* @param t1 the tuple to be multipled
|
||||
* @param t2 the tuple to be added
|
||||
*/
|
||||
public final void scaleAdd(float s, Tuple4f t1, Tuple4f t2) {
|
||||
this.x = s * t1.x + t2.x;
|
||||
this.y = s * t1.y + t2.y;
|
||||
this.z = s * t1.z + t2.z;
|
||||
this.w = s * t1.w + t2.w;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this tuple to the scalar multiplication
|
||||
* of itself and then adds tuple t1 (this = s*this + t1).
|
||||
*
|
||||
* @param s the scalar value
|
||||
* @param t1 the tuple to be added
|
||||
*/
|
||||
public final void scaleAdd(float s, Tuple4f t1) {
|
||||
this.x = s * this.x + t1.x;
|
||||
this.y = s * this.y + t1.y;
|
||||
this.z = s * this.z + t1.z;
|
||||
this.w = s * this.w + t1.w;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string that contains the values of this Tuple4f.
|
||||
* The form is (x,y,z,w).
|
||||
*
|
||||
* @return the String representation
|
||||
*/
|
||||
public String toString() {
|
||||
return "(" + this.x + ", " + this.y + ", " + this.z + ", " + this.w + ")";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if all of the data members of Tuple4f t1 are
|
||||
* equal to the corresponding data members in this Tuple4f.
|
||||
*
|
||||
* @param t1 the vector with which the comparison is made
|
||||
* @return true or false
|
||||
*/
|
||||
public boolean equals(Tuple4f t1) {
|
||||
try {
|
||||
return (this.x == t1.x && this.y == t1.y && this.z == t1.z
|
||||
&& this.w == t1.w);
|
||||
} catch (NullPointerException e2) {
|
||||
Iris.reportError(e2);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the Object t1 is of type Tuple4f and all of the
|
||||
* data members of t1 are equal to the corresponding data members in
|
||||
* this Tuple4f.
|
||||
*
|
||||
* @param t1 the object with which the comparison is made
|
||||
* @return true or false
|
||||
*/
|
||||
public boolean equals(Object t1) {
|
||||
try {
|
||||
Tuple4f t2 = (Tuple4f) t1;
|
||||
return (this.x == t2.x && this.y == t2.y &&
|
||||
this.z == t2.z && this.w == t2.w);
|
||||
} catch (NullPointerException | ClassCastException e2) {
|
||||
Iris.reportError(e2);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the L-infinite distance between this tuple
|
||||
* and tuple t1 is less than or equal to the epsilon parameter,
|
||||
* otherwise returns false. The L-infinite
|
||||
* distance is equal to
|
||||
* MAX[abs(x1-x2), abs(y1-y2), abs(z1-z2), abs(w1-w2)].
|
||||
*
|
||||
* @param t1 the tuple to be compared to this tuple
|
||||
* @param epsilon the threshold value
|
||||
* @return true or false
|
||||
*/
|
||||
public boolean epsilonEquals(Tuple4f t1, float epsilon) {
|
||||
float diff;
|
||||
|
||||
diff = x - t1.x;
|
||||
if (Float.isNaN(diff)) return false;
|
||||
if ((diff < 0 ? -diff : diff) > epsilon) return false;
|
||||
|
||||
diff = y - t1.y;
|
||||
if (Float.isNaN(diff)) return false;
|
||||
if ((diff < 0 ? -diff : diff) > epsilon) return false;
|
||||
|
||||
diff = z - t1.z;
|
||||
if (Float.isNaN(diff)) return false;
|
||||
if ((diff < 0 ? -diff : diff) > epsilon) return false;
|
||||
|
||||
diff = w - t1.w;
|
||||
if (Float.isNaN(diff)) return false;
|
||||
return !((diff < 0 ? -diff : diff) > epsilon);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a hash code value based on the data values in this
|
||||
* object. Two different Tuple4f objects with identical data values
|
||||
* (i.e., Tuple4f.equals returns true) will return the same hash
|
||||
* code value. Two objects with different data members may return the
|
||||
* same hash value, although this is not likely.
|
||||
*
|
||||
* @return the integer hash code value
|
||||
*/
|
||||
public int hashCode() {
|
||||
long bits = 1L;
|
||||
bits = 31L * bits + (long) VecMathUtil.floatToIntBits(x);
|
||||
bits = 31L * bits + (long) VecMathUtil.floatToIntBits(y);
|
||||
bits = 31L * bits + (long) VecMathUtil.floatToIntBits(z);
|
||||
bits = 31L * bits + (long) VecMathUtil.floatToIntBits(w);
|
||||
return (int) (bits ^ (bits >> 32));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clamps the tuple parameter to the range [low, high] and
|
||||
* places the values into this tuple.
|
||||
*
|
||||
* @param min the lowest value in the tuple after clamping
|
||||
* @param max the highest value in the tuple after clamping
|
||||
* @param t the source tuple, which will not be modified
|
||||
*/
|
||||
public final void clamp(float min, float max, Tuple4f t) {
|
||||
if (t.x > max) {
|
||||
x = max;
|
||||
} else x = Math.max(t.x, min);
|
||||
|
||||
if (t.y > max) {
|
||||
y = max;
|
||||
} else y = Math.max(t.y, min);
|
||||
|
||||
if (t.z > max) {
|
||||
z = max;
|
||||
} else z = Math.max(t.z, min);
|
||||
|
||||
if (t.w > max) {
|
||||
w = max;
|
||||
} else w = Math.max(t.w, min);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clamps the minimum value of the tuple parameter to the min
|
||||
* parameter and places the values into this tuple.
|
||||
*
|
||||
* @param min the lowest value in the tuple after clamping
|
||||
* @param t the source tuple, which will not be modified
|
||||
*/
|
||||
public final void clampMin(float min, Tuple4f t) {
|
||||
x = Math.max(t.x, min);
|
||||
|
||||
y = Math.max(t.y, min);
|
||||
|
||||
z = Math.max(t.z, min);
|
||||
|
||||
w = Math.max(t.w, min);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clamps the maximum value of the tuple parameter to the max
|
||||
* parameter and places the values into this tuple.
|
||||
*
|
||||
* @param max the highest value in the tuple after clamping
|
||||
* @param t the source tuple, which will not be modified
|
||||
*/
|
||||
public final void clampMax(float max, Tuple4f t) {
|
||||
x = Math.min(t.x, max);
|
||||
|
||||
y = Math.min(t.y, max);
|
||||
|
||||
z = Math.min(t.z, max);
|
||||
|
||||
if (t.w > max) {
|
||||
w = max;
|
||||
} else {
|
||||
w = t.z;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets each component of the tuple parameter to its absolute
|
||||
* value and places the modified values into this tuple.
|
||||
*
|
||||
* @param t the source tuple, which will not be modified
|
||||
*/
|
||||
public final void absolute(Tuple4f t) {
|
||||
x = Math.abs(t.x);
|
||||
y = Math.abs(t.y);
|
||||
z = Math.abs(t.z);
|
||||
w = Math.abs(t.w);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clamps this tuple to the range [low, high].
|
||||
*
|
||||
* @param min the lowest value in this tuple after clamping
|
||||
* @param max the highest value in this tuple after clamping
|
||||
*/
|
||||
public final void clamp(float min, float max) {
|
||||
if (x > max) {
|
||||
x = max;
|
||||
} else if (x < min) {
|
||||
x = min;
|
||||
}
|
||||
|
||||
if (y > max) {
|
||||
y = max;
|
||||
} else if (y < min) {
|
||||
y = min;
|
||||
}
|
||||
|
||||
if (z > max) {
|
||||
z = max;
|
||||
} else if (z < min) {
|
||||
z = min;
|
||||
}
|
||||
|
||||
if (w > max) {
|
||||
w = max;
|
||||
} else if (w < min) {
|
||||
w = min;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clamps the minimum value of this tuple to the min parameter.
|
||||
*
|
||||
* @param min the lowest value in this tuple after clamping
|
||||
*/
|
||||
public final void clampMin(float min) {
|
||||
if (x < min) x = min;
|
||||
if (y < min) y = min;
|
||||
if (z < min) z = min;
|
||||
if (w < min) w = min;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clamps the maximum value of this tuple to the max parameter.
|
||||
*
|
||||
* @param max the highest value in the tuple after clamping
|
||||
*/
|
||||
public final void clampMax(float max) {
|
||||
if (x > max) x = max;
|
||||
if (y > max) y = max;
|
||||
if (z > max) z = max;
|
||||
if (w > max) w = max;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets each component of this tuple to its absolute value.
|
||||
*/
|
||||
public final void absolute() {
|
||||
x = Math.abs(x);
|
||||
y = Math.abs(y);
|
||||
z = Math.abs(z);
|
||||
w = Math.abs(w);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Linearly interpolates between tuples t1 and t2 and places the
|
||||
* result into this tuple: this = (1-alpha)*t1 + alpha*t2.
|
||||
*
|
||||
* @param t1 the first tuple
|
||||
* @param t2 the second tuple
|
||||
* @param alpha the alpha interpolation parameter
|
||||
*/
|
||||
public void interpolate(Tuple4f t1, Tuple4f t2, float alpha) {
|
||||
this.x = (1 - alpha) * t1.x + alpha * t2.x;
|
||||
this.y = (1 - alpha) * t1.y + alpha * t2.y;
|
||||
this.z = (1 - alpha) * t1.z + alpha * t2.z;
|
||||
this.w = (1 - alpha) * t1.w + alpha * t2.w;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Linearly interpolates between this tuple and tuple t1 and
|
||||
* places the result into this tuple: this = (1-alpha)*this + alpha*t1.
|
||||
*
|
||||
* @param t1 the first tuple
|
||||
* @param alpha the alpha interpolation parameter
|
||||
*/
|
||||
public void interpolate(Tuple4f t1, float alpha) {
|
||||
this.x = (1 - alpha) * this.x + alpha * t1.x;
|
||||
this.y = (1 - alpha) * this.y + alpha * t1.y;
|
||||
this.z = (1 - alpha) * this.z + alpha * t1.z;
|
||||
this.w = (1 - alpha) * this.w + alpha * t1.w;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new object of the same class as this object.
|
||||
*
|
||||
* @return a clone of this instance.
|
||||
* @throws OutOfMemoryError if there is not enough memory.
|
||||
* @see java.lang.Cloneable
|
||||
* @since vecmath 1.3
|
||||
*/
|
||||
public Object clone() {
|
||||
// Since there are no arrays we can just use Object.clone()
|
||||
try {
|
||||
return super.clone();
|
||||
} catch (CloneNotSupportedException e) {Iris.reportError(e);
|
||||
// this shouldn't happen, since we are Cloneable
|
||||
throw new InternalError();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the <i>x</i> coordinate.
|
||||
*
|
||||
* @return the <i>x</i> coordinate.
|
||||
* @since vecmath 1.5
|
||||
*/
|
||||
public final float getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the <i>x</i> coordinate.
|
||||
*
|
||||
* @param x value to <i>x</i> coordinate.
|
||||
* @since vecmath 1.5
|
||||
*/
|
||||
public final void setX(float x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the <i>y</i> coordinate.
|
||||
*
|
||||
* @return the <i>y</i> coordinate.
|
||||
* @since vecmath 1.5
|
||||
*/
|
||||
public final float getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the <i>y</i> coordinate.
|
||||
*
|
||||
* @param y value to <i>y</i> coordinate.
|
||||
* @since vecmath 1.5
|
||||
*/
|
||||
public final void setY(float y) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the <i>z</i> coordinate.
|
||||
*
|
||||
* @return the <i>z</i> coordinate.
|
||||
* @since vecmath 1.5
|
||||
*/
|
||||
public final float getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the <i>z</i> coordinate.
|
||||
*
|
||||
* @param z value to <i>z</i> coordinate.
|
||||
* @since vecmath 1.5
|
||||
*/
|
||||
public final void setZ(float z) {
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the <i>w</i> coordinate.
|
||||
*
|
||||
* @return the <i>w</i> coordinate.
|
||||
* @since vecmath 1.5
|
||||
*/
|
||||
public final float getW() {
|
||||
return w;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the <i>w</i> coordinate.
|
||||
*
|
||||
* @param w value to <i>w</i> coordinate.
|
||||
* @since vecmath 1.5
|
||||
*/
|
||||
public final void setW(float w) {
|
||||
this.w = w;
|
||||
}
|
||||
}
|
||||
88
src/main/java/com/volmit/iris/util/math/VecMathUtil.java
Normal file
88
src/main/java/com/volmit/iris/util/math/VecMathUtil.java
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.math;
|
||||
|
||||
/**
|
||||
* Utility vecmath class used when computing the hash code for vecmath
|
||||
* objects containing float or double values. This fixes Issue 36.
|
||||
*/
|
||||
class VecMathUtil {
|
||||
/**
|
||||
* Returns the representation of the specified floating-point
|
||||
* value according to the IEEE 754 floating-point "single format"
|
||||
* bit layout, after first mapping -0.0 to 0.0. This method is
|
||||
* identical to Float.floatToIntBits(float) except that an integer
|
||||
* value of 0 is returned for a floating-point value of
|
||||
* -0.0f. This is done for the purpose of computing a hash code
|
||||
* that satisfies the contract of hashCode() and equals(). The
|
||||
* equals() method in each vecmath class does a pair-wise "=="
|
||||
* test on each floating-point field in the class (e.g., x, y, and
|
||||
* z for a Tuple3f). Since 0.0f == -0.0f returns true,
|
||||
* we must also return the same hash code for two objects, one of
|
||||
* which has a field with a value of -0.0f and the other of which
|
||||
* has a cooresponding field with a value of 0.0f.
|
||||
*
|
||||
* @param f an input floating-point number
|
||||
* @return the integer bits representing that floating-point
|
||||
* number, after first mapping -0.0f to 0.0f
|
||||
*/
|
||||
static int floatToIntBits(float f) {
|
||||
// Check for +0 or -0
|
||||
if (f == 0.0f) {
|
||||
return 0;
|
||||
} else {
|
||||
return Float.floatToIntBits(f);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the representation of the specified floating-point
|
||||
* value according to the IEEE 754 floating-point "double format"
|
||||
* bit layout, after first mapping -0.0 to 0.0. This method is
|
||||
* identical to Double.doubleToLongBits(double) except that an
|
||||
* integer value of 0L is returned for a floating-point value of
|
||||
* -0.0. This is done for the purpose of computing a hash code
|
||||
* that satisfies the contract of hashCode() and equals(). The
|
||||
* equals() method in each vecmath class does a pair-wise "=="
|
||||
* test on each floating-point field in the class (e.g., x, y, and
|
||||
* z for a Tuple3d). Since 0.0 == -0.0 returns true, we
|
||||
* must also return the same hash code for two objects, one of
|
||||
* which has a field with a value of -0.0 and the other of which
|
||||
* has a cooresponding field with a value of 0.0.
|
||||
*
|
||||
* @param d an input double precision floating-point number
|
||||
* @return the integer bits representing that floating-point
|
||||
* number, after first mapping -0.0f to 0.0f
|
||||
*/
|
||||
static long doubleToLongBits(double d) {
|
||||
// Check for +0 or -0
|
||||
if (d == 0.0) {
|
||||
return 0L;
|
||||
} else {
|
||||
return Double.doubleToLongBits(d);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Do not construct an instance of this class.
|
||||
*/
|
||||
private VecMathUtil() {
|
||||
}
|
||||
}
|
||||
168
src/main/java/com/volmit/iris/util/math/Vector2d.java
Normal file
168
src/main/java/com/volmit/iris/util/math/Vector2d.java
Normal file
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.math;
|
||||
|
||||
/**
|
||||
* A 2-element vector that is represented by double-precision floating
|
||||
* point x,y coordinates.
|
||||
*/
|
||||
public class Vector2d extends Tuple2d implements java.io.Serializable {
|
||||
|
||||
// Combatible with 1.1
|
||||
static final long serialVersionUID = 8572646365302599857L;
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Vector2d from the specified xy coordinates.
|
||||
*
|
||||
* @param x the x coordinate
|
||||
* @param y the y coordinate
|
||||
*/
|
||||
public Vector2d(double x, double y) {
|
||||
super(x, y);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Vector2d from the specified array.
|
||||
*
|
||||
* @param v the array of length 2 containing xy in order
|
||||
*/
|
||||
public Vector2d(double[] v) {
|
||||
super(v);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Vector2d from the specified Vector2d.
|
||||
*
|
||||
* @param v1 the Vector2d containing the initialization x y data
|
||||
*/
|
||||
public Vector2d(Vector2d v1) {
|
||||
super(v1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Vector2d from the specified Vector2f.
|
||||
*
|
||||
* @param v1 the Vector2f containing the initialization x y data
|
||||
*/
|
||||
public Vector2d(Vector2f v1) {
|
||||
super(v1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Vector2d from the specified Tuple2d.
|
||||
*
|
||||
* @param t1 the Tuple2d containing the initialization x y data
|
||||
*/
|
||||
public Vector2d(Tuple2d t1) {
|
||||
super(t1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Vector2d from the specified Tuple2f.
|
||||
*
|
||||
* @param t1 the Tuple2f containing the initialization x y data
|
||||
*/
|
||||
public Vector2d(Tuple2f t1) {
|
||||
super(t1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Vector2d to (0,0).
|
||||
*/
|
||||
public Vector2d() {
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Computes the dot product of the this vector and vector v1.
|
||||
*
|
||||
* @param v1 the other vector
|
||||
*/
|
||||
public final double dot(Vector2d v1) {
|
||||
return (this.x * v1.x + this.y * v1.y);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the length of this vector.
|
||||
*
|
||||
* @return the length of this vector
|
||||
*/
|
||||
public final double length() {
|
||||
return Math.sqrt(this.x * this.x + this.y * this.y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the squared length of this vector.
|
||||
*
|
||||
* @return the squared length of this vector
|
||||
*/
|
||||
public final double lengthSquared() {
|
||||
return (this.x * this.x + this.y * this.y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of this vector to the normalization of vector v1.
|
||||
*
|
||||
* @param v1 the un-normalized vector
|
||||
*/
|
||||
public final void normalize(Vector2d v1) {
|
||||
double norm;
|
||||
|
||||
norm = 1.0 / Math.sqrt(v1.x * v1.x + v1.y * v1.y);
|
||||
this.x = v1.x * norm;
|
||||
this.y = v1.y * norm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes this vector in place.
|
||||
*/
|
||||
public final void normalize() {
|
||||
double norm;
|
||||
|
||||
norm = 1.0 / Math.sqrt(this.x * this.x + this.y * this.y);
|
||||
this.x *= norm;
|
||||
this.y *= norm;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the angle in radians between this vector and the vector
|
||||
* parameter; the return value is constrained to the range [0,PI].
|
||||
*
|
||||
* @param v1 the other vector
|
||||
* @return the angle in radians in the range [0,PI]
|
||||
*/
|
||||
public final double angle(Vector2d v1) {
|
||||
double vDot = this.dot(v1) / (this.length() * v1.length());
|
||||
if (vDot < -1.0) vDot = -1.0;
|
||||
if (vDot > 1.0) vDot = 1.0;
|
||||
return Math.acos(vDot);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
168
src/main/java/com/volmit/iris/util/math/Vector2f.java
Normal file
168
src/main/java/com/volmit/iris/util/math/Vector2f.java
Normal file
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.math;
|
||||
|
||||
/**
|
||||
* A 2-element vector that is represented by single-precision floating
|
||||
* point x,y coordinates.
|
||||
*/
|
||||
public class Vector2f extends Tuple2f implements java.io.Serializable {
|
||||
|
||||
// Combatible with 1.1
|
||||
static final long serialVersionUID = -2168194326883512320L;
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Vector2f from the specified xy coordinates.
|
||||
*
|
||||
* @param x the x coordinate
|
||||
* @param y the y coordinate
|
||||
*/
|
||||
public Vector2f(float x, float y) {
|
||||
super(x, y);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Vector2f from the specified array.
|
||||
*
|
||||
* @param v the array of length 2 containing xy in order
|
||||
*/
|
||||
public Vector2f(float[] v) {
|
||||
super(v);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Vector2f from the specified Vector2f.
|
||||
*
|
||||
* @param v1 the Vector2f containing the initialization x y data
|
||||
*/
|
||||
public Vector2f(Vector2f v1) {
|
||||
super(v1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Vector2f from the specified Vector2d.
|
||||
*
|
||||
* @param v1 the Vector2d containing the initialization x y data
|
||||
*/
|
||||
public Vector2f(Vector2d v1) {
|
||||
super(v1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Vector2f from the specified Tuple2f.
|
||||
*
|
||||
* @param t1 the Tuple2f containing the initialization x y data
|
||||
*/
|
||||
public Vector2f(Tuple2f t1) {
|
||||
super(t1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Vector2f from the specified Tuple2d.
|
||||
*
|
||||
* @param t1 the Tuple2d containing the initialization x y data
|
||||
*/
|
||||
public Vector2f(Tuple2d t1) {
|
||||
super(t1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Vector2f to (0,0).
|
||||
*/
|
||||
public Vector2f() {
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Computes the dot product of the this vector and vector v1.
|
||||
*
|
||||
* @param v1 the other vector
|
||||
*/
|
||||
public final float dot(Vector2f v1) {
|
||||
return (this.x * v1.x + this.y * v1.y);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the length of this vector.
|
||||
*
|
||||
* @return the length of this vector
|
||||
*/
|
||||
public final float length() {
|
||||
return (float) Math.sqrt(this.x * this.x + this.y * this.y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the squared length of this vector.
|
||||
*
|
||||
* @return the squared length of this vector
|
||||
*/
|
||||
public final float lengthSquared() {
|
||||
return (this.x * this.x + this.y * this.y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of this vector to the normalization of vector v1.
|
||||
*
|
||||
* @param v1 the un-normalized vector
|
||||
*/
|
||||
public final void normalize(Vector2f v1) {
|
||||
float norm;
|
||||
|
||||
norm = (float) (1.0 / Math.sqrt(v1.x * v1.x + v1.y * v1.y));
|
||||
this.x = v1.x * norm;
|
||||
this.y = v1.y * norm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes this vector in place.
|
||||
*/
|
||||
public final void normalize() {
|
||||
float norm;
|
||||
|
||||
norm = (float)
|
||||
(1.0 / Math.sqrt(this.x * this.x + this.y * this.y));
|
||||
this.x *= norm;
|
||||
this.y *= norm;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the angle in radians between this vector and the vector
|
||||
* parameter; the return value is constrained to the range [0,PI].
|
||||
*
|
||||
* @param v1 the other vector
|
||||
* @return the angle in radians in the range [0,PI]
|
||||
*/
|
||||
public final float angle(Vector2f v1) {
|
||||
double vDot = this.dot(v1) / (this.length() * v1.length());
|
||||
if (vDot < -1.0) vDot = -1.0;
|
||||
if (vDot > 1.0) vDot = 1.0;
|
||||
return ((float) (Math.acos(vDot)));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
192
src/main/java/com/volmit/iris/util/math/Vector3d.java
Normal file
192
src/main/java/com/volmit/iris/util/math/Vector3d.java
Normal file
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.math;
|
||||
|
||||
/**
|
||||
* A 3-element vector that is represented by double-precision floating point
|
||||
* x,y,z coordinates. If this value represents a normal, then it should
|
||||
* be normalized.
|
||||
*/
|
||||
public class Vector3d extends Tuple3d implements java.io.Serializable {
|
||||
|
||||
// Combatible with 1.1
|
||||
static final long serialVersionUID = 3761969948420550442L;
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Vector3d from the specified xyz coordinates.
|
||||
*
|
||||
* @param x the x coordinate
|
||||
* @param y the y coordinate
|
||||
* @param z the z coordinate
|
||||
*/
|
||||
public Vector3d(double x, double y, double z) {
|
||||
super(x, y, z);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Vector3d from the array of length 3.
|
||||
*
|
||||
* @param v the array of length 3 containing xyz in order
|
||||
*/
|
||||
public Vector3d(double[] v) {
|
||||
super(v);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Vector3d from the specified Vector3d.
|
||||
*
|
||||
* @param v1 the Vector3d containing the initialization x y z data
|
||||
*/
|
||||
public Vector3d(Vector3d v1) {
|
||||
super(v1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Vector3d from the specified Vector3f.
|
||||
*
|
||||
* @param v1 the Vector3f containing the initialization x y z data
|
||||
*/
|
||||
public Vector3d(Vector3f v1) {
|
||||
super(v1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Vector3d from the specified Tuple3f.
|
||||
*
|
||||
* @param t1 the Tuple3f containing the initialization x y z data
|
||||
*/
|
||||
public Vector3d(Tuple3f t1) {
|
||||
super(t1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Vector3d from the specified Tuple3d.
|
||||
*
|
||||
* @param t1 the Tuple3d containing the initialization x y z data
|
||||
*/
|
||||
public Vector3d(Tuple3d t1) {
|
||||
super(t1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Vector3d to (0,0,0).
|
||||
*/
|
||||
public Vector3d() {
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets this vector to the vector cross product of vectors v1 and v2.
|
||||
*
|
||||
* @param v1 the first vector
|
||||
* @param v2 the second vector
|
||||
*/
|
||||
public final void cross(Vector3d v1, Vector3d v2) {
|
||||
double x, y;
|
||||
|
||||
x = v1.y * v2.z - v1.z * v2.y;
|
||||
y = v2.x * v1.z - v2.z * v1.x;
|
||||
this.z = v1.x * v2.y - v1.y * v2.x;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this vector to the normalization of vector v1.
|
||||
*
|
||||
* @param v1 the un-normalized vector
|
||||
*/
|
||||
public final void normalize(Vector3d v1) {
|
||||
double norm;
|
||||
|
||||
norm = 1.0 / Math.sqrt(v1.x * v1.x + v1.y * v1.y + v1.z * v1.z);
|
||||
this.x = v1.x * norm;
|
||||
this.y = v1.y * norm;
|
||||
this.z = v1.z * norm;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Normalizes this vector in place.
|
||||
*/
|
||||
public final void normalize() {
|
||||
double norm;
|
||||
|
||||
norm = 1.0 / Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
|
||||
this.x *= norm;
|
||||
this.y *= norm;
|
||||
this.z *= norm;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the dot product of this vector and vector v1.
|
||||
*
|
||||
* @param v1 the other vector
|
||||
* @return the dot product of this and v1
|
||||
*/
|
||||
public final double dot(Vector3d v1) {
|
||||
return (this.x * v1.x + this.y * v1.y + this.z * v1.z);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the squared length of this vector.
|
||||
*
|
||||
* @return the squared length of this vector
|
||||
*/
|
||||
public final double lengthSquared() {
|
||||
return (this.x * this.x + this.y * this.y + this.z * this.z);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the length of this vector.
|
||||
*
|
||||
* @return the length of this vector
|
||||
*/
|
||||
public final double length() {
|
||||
return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the angle in radians between this vector and the vector
|
||||
* parameter; the return value is constrained to the range [0,PI].
|
||||
*
|
||||
* @param v1 the other vector
|
||||
* @return the angle in radians in the range [0,PI]
|
||||
*/
|
||||
public final double angle(Vector3d v1) {
|
||||
double vDot = this.dot(v1) / (this.length() * v1.length());
|
||||
if (vDot < -1.0) vDot = -1.0;
|
||||
if (vDot > 1.0) vDot = 1.0;
|
||||
return Math.acos(vDot);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
189
src/main/java/com/volmit/iris/util/math/Vector3f.java
Normal file
189
src/main/java/com/volmit/iris/util/math/Vector3f.java
Normal file
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.math;
|
||||
|
||||
/**
|
||||
* A 3-element vector that is represented by single-precision floating point
|
||||
* x,y,z coordinates. If this value represents a normal, then it should
|
||||
* be normalized.
|
||||
*/
|
||||
public class Vector3f extends Tuple3f implements java.io.Serializable {
|
||||
|
||||
// Combatible with 1.1
|
||||
static final long serialVersionUID = -7031930069184524614L;
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Vector3f from the specified xyz coordinates.
|
||||
*
|
||||
* @param x the x coordinate
|
||||
* @param y the y coordinate
|
||||
* @param z the z coordinate
|
||||
*/
|
||||
public Vector3f(float x, float y, float z) {
|
||||
super(x, y, z);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Vector3f from the array of length 3.
|
||||
*
|
||||
* @param v the array of length 3 containing xyz in order
|
||||
*/
|
||||
public Vector3f(float[] v) {
|
||||
super(v);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Vector3f from the specified Vector3f.
|
||||
*
|
||||
* @param v1 the Vector3f containing the initialization x y z data
|
||||
*/
|
||||
public Vector3f(Vector3f v1) {
|
||||
super(v1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Vector3f from the specified Vector3d.
|
||||
*
|
||||
* @param v1 the Vector3d containing the initialization x y z data
|
||||
*/
|
||||
public Vector3f(Vector3d v1) {
|
||||
super(v1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Vector3f from the specified Tuple3f.
|
||||
*
|
||||
* @param t1 the Tuple3f containing the initialization x y z data
|
||||
*/
|
||||
public Vector3f(Tuple3f t1) {
|
||||
super(t1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Vector3f from the specified Tuple3d.
|
||||
*
|
||||
* @param t1 the Tuple3d containing the initialization x y z data
|
||||
*/
|
||||
public Vector3f(Tuple3d t1) {
|
||||
super(t1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs and initializes a Vector3f to (0,0,0).
|
||||
*/
|
||||
public Vector3f() {
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the squared length of this vector.
|
||||
*
|
||||
* @return the squared length of this vector
|
||||
*/
|
||||
public final float lengthSquared() {
|
||||
return (this.x * this.x + this.y * this.y + this.z * this.z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of this vector.
|
||||
*
|
||||
* @return the length of this vector
|
||||
*/
|
||||
public final float length() {
|
||||
return (float)
|
||||
Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets this vector to be the vector cross product of vectors v1 and v2.
|
||||
*
|
||||
* @param v1 the first vector
|
||||
* @param v2 the second vector
|
||||
*/
|
||||
public final void cross(Vector3f v1, Vector3f v2) {
|
||||
float x, y;
|
||||
|
||||
x = v1.y * v2.z - v1.z * v2.y;
|
||||
y = v2.x * v1.z - v2.z * v1.x;
|
||||
this.z = v1.x * v2.y - v1.y * v2.x;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the dot product of this vector and vector v1.
|
||||
*
|
||||
* @param v1 the other vector
|
||||
* @return the dot product of this vector and v1
|
||||
*/
|
||||
public final float dot(Vector3f v1) {
|
||||
return (this.x * v1.x + this.y * v1.y + this.z * v1.z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of this vector to the normalization of vector v1.
|
||||
*
|
||||
* @param v1 the un-normalized vector
|
||||
*/
|
||||
public final void normalize(Vector3f v1) {
|
||||
float norm;
|
||||
|
||||
norm = (float) (1.0 / Math.sqrt(v1.x * v1.x + v1.y * v1.y + v1.z * v1.z));
|
||||
this.x = v1.x * norm;
|
||||
this.y = v1.y * norm;
|
||||
this.z = v1.z * norm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes this vector in place.
|
||||
*/
|
||||
public final void normalize() {
|
||||
float norm;
|
||||
|
||||
norm = (float)
|
||||
(1.0 / Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z));
|
||||
this.x *= norm;
|
||||
this.y *= norm;
|
||||
this.z *= norm;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the angle in radians between this vector and the vector
|
||||
* parameter; the return value is constrained to the range [0,PI].
|
||||
*
|
||||
* @param v1 the other vector
|
||||
* @return the angle in radians in the range [0,PI]
|
||||
*/
|
||||
public final float angle(Vector3f v1) {
|
||||
double vDot = this.dot(v1) / (this.length() * v1.length());
|
||||
if (vDot < -1.0) vDot = -1.0;
|
||||
if (vDot > 1.0) vDot = 1.0;
|
||||
return ((float) (Math.acos(vDot)));
|
||||
}
|
||||
|
||||
}
|
||||
617
src/main/java/com/volmit/iris/util/math/VectorMath.java
Normal file
617
src/main/java/com/volmit/iris/util/math/VectorMath.java
Normal file
@@ -0,0 +1,617 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.math;
|
||||
|
||||
import com.volmit.iris.util.Form;
|
||||
import com.volmit.iris.util.GListAdapter;
|
||||
import com.volmit.iris.util.KList;
|
||||
import org.bukkit.Axis;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
/**
|
||||
* Vector utilities
|
||||
*
|
||||
* @author cyberpwn
|
||||
*/
|
||||
public class VectorMath {
|
||||
public static Vector scaleStatic(Axis x, Vector v, double amt) {
|
||||
return switch (x) {
|
||||
case X -> scaleX(v, amt);
|
||||
case Y -> scaleY(v, amt);
|
||||
case Z -> scaleZ(v, amt);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
public static Vector scaleX(Vector v, double amt) {
|
||||
double x = v.getX();
|
||||
double y = v.getY();
|
||||
double z = v.getZ();
|
||||
double rx = x == 0 ? 1 : amt / x;
|
||||
|
||||
return new Vector(x * rx, y * rx, z * rx);
|
||||
}
|
||||
|
||||
public static Vector scaleY(Vector v, double amt) {
|
||||
double x = v.getX();
|
||||
double y = v.getY();
|
||||
double z = v.getZ();
|
||||
double rx = y == 0 ? 1 : amt / y;
|
||||
|
||||
return new Vector(x * rx, y * rx, z * rx);
|
||||
}
|
||||
|
||||
public static Vector scaleZ(Vector v, double amt) {
|
||||
double x = v.getX();
|
||||
double y = v.getY();
|
||||
double z = v.getZ();
|
||||
double rx = z == 0 ? 1 : amt / z;
|
||||
|
||||
return new Vector(x * rx, y * rx, z * rx);
|
||||
}
|
||||
|
||||
public static Vector reverseXZ(Vector v) {
|
||||
v.setX(-v.getX());
|
||||
v.setZ(-v.getZ());
|
||||
return v;
|
||||
}
|
||||
|
||||
public static boolean isLookingNear(Location a, Location b, double maxOff) {
|
||||
Vector perfect = VectorMath.direction(a, b);
|
||||
Vector actual = a.getDirection();
|
||||
|
||||
return perfect.distance(actual) <= maxOff;
|
||||
}
|
||||
|
||||
public static Vector rotate(Direction current, Direction to, Vector v) {
|
||||
if (current.equals(to)) {
|
||||
return v;
|
||||
} else if (current.equals(to.reverse())) {
|
||||
if (current.isVertical()) {
|
||||
return new Vector(v.getX(), -v.getY(), v.getZ());
|
||||
} else {
|
||||
return new Vector(-v.getX(), v.getY(), -v.getZ());
|
||||
}
|
||||
} else {
|
||||
Vector c = current.toVector().clone().add(to.toVector());
|
||||
|
||||
if (c.getX() == 0) {
|
||||
if (c.getY() != c.getZ()) {
|
||||
return rotate90CX(v);
|
||||
}
|
||||
|
||||
return rotate90CCX(v);
|
||||
} else if (c.getY() == 0) {
|
||||
if (c.getX() != c.getZ()) {
|
||||
return rotate90CY(v);
|
||||
}
|
||||
|
||||
return rotate90CCY(v);
|
||||
} else if (c.getZ() == 0) {
|
||||
if (c.getX() != c.getY()) {
|
||||
return rotate90CZ(v);
|
||||
}
|
||||
|
||||
return rotate90CCZ(v);
|
||||
}
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
// Y X 0 0
|
||||
// X Z 0 0
|
||||
|
||||
// 0 X Y 0
|
||||
// 0 Z X 0
|
||||
|
||||
public static Vector rotate(Direction current, Direction to, Vector v, int w, int h, int d) {
|
||||
if (current.equals(to)) {
|
||||
return v;
|
||||
} else if (current.equals(to.reverse())) {
|
||||
if (current.isVertical()) {
|
||||
return new Vector(v.getX(), -v.getY() + h, v.getZ());
|
||||
} else {
|
||||
return new Vector(-v.getX() + w, v.getY(), -v.getZ() + d);
|
||||
}
|
||||
} else {
|
||||
Vector c = current.toVector().clone().add(to.toVector());
|
||||
|
||||
if (c.getX() == 0) {
|
||||
if (c.getY() != c.getZ()) {
|
||||
return rotate90CX(v, d);
|
||||
}
|
||||
|
||||
return rotate90CCX(v, h);
|
||||
} else if (c.getY() == 0) {
|
||||
if (c.getX() != c.getZ()) {
|
||||
return rotate90CY(v, d);
|
||||
}
|
||||
|
||||
return rotate90CCY(v, w);
|
||||
} else if (c.getZ() == 0) {
|
||||
if (c.getX() != c.getY()) {
|
||||
return rotate90CZ(v, w);
|
||||
}
|
||||
|
||||
return rotate90CCZ(v, h);
|
||||
}
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
public static Vector rotate90CX(Vector v) {
|
||||
return new Vector(v.getX(), -v.getZ(), v.getY());
|
||||
}
|
||||
|
||||
public static Vector rotate90CCX(Vector v) {
|
||||
return new Vector(v.getX(), v.getZ(), -v.getY());
|
||||
}
|
||||
|
||||
public static Vector rotate90CY(Vector v) {
|
||||
return new Vector(-v.getZ(), v.getY(), v.getX());
|
||||
}
|
||||
|
||||
public static Vector rotate90CCY(Vector v) {
|
||||
return new Vector(v.getZ(), v.getY(), -v.getX());
|
||||
}
|
||||
|
||||
public static Vector rotate90CZ(Vector v) {
|
||||
return new Vector(v.getY(), -v.getX(), v.getZ());
|
||||
}
|
||||
|
||||
public static Vector rotate90CCZ(Vector v) {
|
||||
return new Vector(-v.getY(), v.getX(), v.getZ());
|
||||
}
|
||||
|
||||
public static Vector rotate90CX(Vector v, int s) {
|
||||
return new Vector(v.getX(), -v.getZ() + s, v.getY());
|
||||
}
|
||||
|
||||
public static Vector rotate90CCX(Vector v, int s) {
|
||||
return new Vector(v.getX(), v.getZ(), -v.getY() + s);
|
||||
}
|
||||
|
||||
public static Vector rotate90CY(Vector v, int s) {
|
||||
return new Vector(-v.getZ() + s, v.getY(), v.getX());
|
||||
}
|
||||
|
||||
public static Vector rotate90CCY(Vector v, int s) {
|
||||
return new Vector(v.getZ(), v.getY(), -v.getX() + s);
|
||||
}
|
||||
|
||||
public static Vector rotate90CZ(Vector v, int s) {
|
||||
return new Vector(v.getY(), -v.getX() + s, v.getZ());
|
||||
}
|
||||
|
||||
public static Vector rotate90CCZ(Vector v, int s) {
|
||||
return new Vector(-v.getY() + s, v.getX(), v.getZ());
|
||||
}
|
||||
|
||||
public static Vector getAxis(Direction current, Direction to) {
|
||||
if (current.equals(Direction.U) || current.equals(Direction.D)) {
|
||||
if (to.equals(Direction.U) || to.equals(Direction.D)) {
|
||||
return new Vector(1, 0, 0);
|
||||
} else {
|
||||
if (current.equals(Direction.N) || current.equals(Direction.S)) {
|
||||
return Direction.E.toVector();
|
||||
} else {
|
||||
return Direction.S.toVector();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new Vector(0, 1, 0);
|
||||
}
|
||||
|
||||
private static double round(double value, int precision) {
|
||||
return Double.parseDouble(Form.f(value, precision));
|
||||
}
|
||||
|
||||
public static Vector clip(Vector v, int decimals) {
|
||||
v.setX(round(v.getX(), decimals));
|
||||
v.setY(round(v.getY(), decimals));
|
||||
v.setZ(round(v.getZ(), decimals));
|
||||
return v;
|
||||
}
|
||||
|
||||
public static Vector rotateVectorCC(Vector vec, Vector axis, double deg) {
|
||||
double theta = Math.toRadians(deg);
|
||||
double x, y, z;
|
||||
double u, v, w;
|
||||
x = vec.getX();
|
||||
y = vec.getY();
|
||||
z = vec.getZ();
|
||||
u = axis.getX();
|
||||
v = axis.getY();
|
||||
w = axis.getZ();
|
||||
double f = u * x + v * y + w * z;
|
||||
double xPrime = u * (f) * (1d - Math.cos(theta)) + x * Math.cos(theta) + (-w * y + v * z) * Math.sin(theta);
|
||||
double yPrime = v * (f) * (1d - Math.cos(theta)) + y * Math.cos(theta) + (w * x - u * z) * Math.sin(theta);
|
||||
double zPrime = w * (f) * (1d - Math.cos(theta)) + z * Math.cos(theta) + (-v * x + u * y) * Math.sin(theta);
|
||||
|
||||
return clip(new Vector(xPrime, yPrime, zPrime), 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all SIMPLE block faces from a more specific block face (SOUTH_EAST) =
|
||||
* (south, east)
|
||||
*
|
||||
* @param f the block face
|
||||
* @return multiple faces, or one if the face is already simple
|
||||
*/
|
||||
public static KList<BlockFace> split(BlockFace f) {
|
||||
KList<BlockFace> faces = new KList<>();
|
||||
|
||||
switch (f) {
|
||||
case DOWN:
|
||||
faces.add(BlockFace.DOWN);
|
||||
break;
|
||||
case EAST:
|
||||
faces.add(BlockFace.EAST);
|
||||
break;
|
||||
case EAST_NORTH_EAST:
|
||||
faces.add(BlockFace.EAST);
|
||||
faces.add(BlockFace.EAST);
|
||||
faces.add(BlockFace.NORTH);
|
||||
break;
|
||||
case EAST_SOUTH_EAST:
|
||||
faces.add(BlockFace.EAST);
|
||||
faces.add(BlockFace.EAST);
|
||||
faces.add(BlockFace.SOUTH);
|
||||
break;
|
||||
case NORTH:
|
||||
faces.add(BlockFace.NORTH);
|
||||
break;
|
||||
case NORTH_EAST:
|
||||
faces.add(BlockFace.NORTH);
|
||||
faces.add(BlockFace.EAST);
|
||||
break;
|
||||
case NORTH_NORTH_EAST:
|
||||
faces.add(BlockFace.NORTH);
|
||||
faces.add(BlockFace.NORTH);
|
||||
faces.add(BlockFace.EAST);
|
||||
break;
|
||||
case NORTH_NORTH_WEST:
|
||||
faces.add(BlockFace.NORTH);
|
||||
faces.add(BlockFace.NORTH);
|
||||
faces.add(BlockFace.WEST);
|
||||
break;
|
||||
case NORTH_WEST:
|
||||
faces.add(BlockFace.NORTH);
|
||||
faces.add(BlockFace.WEST);
|
||||
break;
|
||||
case SELF:
|
||||
faces.add(BlockFace.SELF);
|
||||
break;
|
||||
case SOUTH:
|
||||
faces.add(BlockFace.SOUTH);
|
||||
break;
|
||||
case SOUTH_EAST:
|
||||
faces.add(BlockFace.SOUTH);
|
||||
faces.add(BlockFace.EAST);
|
||||
break;
|
||||
case SOUTH_SOUTH_EAST:
|
||||
faces.add(BlockFace.SOUTH);
|
||||
faces.add(BlockFace.SOUTH);
|
||||
faces.add(BlockFace.EAST);
|
||||
break;
|
||||
case SOUTH_SOUTH_WEST:
|
||||
faces.add(BlockFace.SOUTH);
|
||||
faces.add(BlockFace.SOUTH);
|
||||
faces.add(BlockFace.WEST);
|
||||
break;
|
||||
case SOUTH_WEST:
|
||||
faces.add(BlockFace.SOUTH);
|
||||
faces.add(BlockFace.WEST);
|
||||
break;
|
||||
case UP:
|
||||
faces.add(BlockFace.UP);
|
||||
break;
|
||||
case WEST:
|
||||
faces.add(BlockFace.WEST);
|
||||
break;
|
||||
case WEST_NORTH_WEST:
|
||||
faces.add(BlockFace.WEST);
|
||||
faces.add(BlockFace.WEST);
|
||||
faces.add(BlockFace.NORTH);
|
||||
break;
|
||||
case WEST_SOUTH_WEST:
|
||||
faces.add(BlockFace.WEST);
|
||||
faces.add(BlockFace.WEST);
|
||||
faces.add(BlockFace.SOUTH);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return faces;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a normalized vector going from a location to another
|
||||
*
|
||||
* @param from from here
|
||||
* @param to to here
|
||||
* @return the normalized vector direction
|
||||
*/
|
||||
public static Vector direction(Location from, Location to) {
|
||||
return to.clone().subtract(from.clone()).toVector().normalize();
|
||||
}
|
||||
|
||||
public static Vector directionNoNormal(Location from, Location to) {
|
||||
return to.clone().subtract(from.clone()).toVector();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the vector direction from the yaw and pitch
|
||||
*
|
||||
* @param yaw the yaw
|
||||
* @param pitch the pitch
|
||||
* @return the vector
|
||||
*/
|
||||
public static Vector toVector(float yaw, float pitch) {
|
||||
return new Vector(Math.cos(pitch) * Math.cos(yaw), Math.sin(pitch), Math.cos(pitch) * Math.sin(-yaw));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an impulse (force) to an entity
|
||||
*
|
||||
* @param e the entity
|
||||
* @param v the vector
|
||||
*/
|
||||
public static void impulse(Entity e, Vector v) {
|
||||
impulse(e, v, 1.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an impulse (force) on an entity
|
||||
*
|
||||
* @param e the entity
|
||||
* @param v the vector
|
||||
* @param effectiveness the effectiveness
|
||||
*/
|
||||
public static void impulse(Entity e, Vector v, double effectiveness) {
|
||||
Vector vx = e.getVelocity();
|
||||
vx.add(v.clone().multiply(effectiveness));
|
||||
e.setVelocity(vx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse a direction
|
||||
*
|
||||
* @param v the direction
|
||||
* @return the reversed direction
|
||||
*/
|
||||
public static Vector reverse(Vector v) {
|
||||
if (v.getX() != 0) {
|
||||
v.setX(-v.getX());
|
||||
}
|
||||
|
||||
if (v.getY() != 0) {
|
||||
v.setY(-v.getY());
|
||||
}
|
||||
|
||||
if (v.getZ() != 0) {
|
||||
v.setZ(-v.getZ());
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a speed value from a vector (velocity)
|
||||
*
|
||||
* @param v the vector
|
||||
* @return the speed
|
||||
*/
|
||||
public static double getSpeed(Vector v) {
|
||||
Vector vi = new Vector(0, 0, 0);
|
||||
Vector vt = new Vector(0, 0, 0).add(v);
|
||||
|
||||
return vi.distance(vt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shift all vectors based on the given vector
|
||||
*
|
||||
* @param vector the vector direction to shift the vectors
|
||||
* @param vectors the vectors to be shifted
|
||||
* @return the shifted vectors
|
||||
*/
|
||||
public static KList<Vector> shift(Vector vector, KList<Vector> vectors) {
|
||||
return new KList<>(new GListAdapter<Vector, Vector>() {
|
||||
@Override
|
||||
public Vector onAdapt(Vector from) {
|
||||
return from.add(vector);
|
||||
}
|
||||
}.adapt(vectors));
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to get the blockFace for the vector (will be tri-normalized)
|
||||
*
|
||||
* @param v the vector
|
||||
* @return the block face or null
|
||||
*/
|
||||
public static BlockFace getBlockFace(Vector v) {
|
||||
Vector p = triNormalize(v);
|
||||
|
||||
for (BlockFace i : BlockFace.values()) {
|
||||
if (p.getX() == i.getModX() && p.getY() == i.getModY() && p.getZ() == i.getModZ()) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
for (BlockFace i : BlockFace.values()) {
|
||||
if (p.getX() == i.getModX() && p.getZ() == i.getModZ()) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
for (BlockFace i : BlockFace.values()) {
|
||||
if (p.getY() == i.getModY() && p.getZ() == i.getModZ()) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
for (BlockFace i : BlockFace.values()) {
|
||||
if (p.getX() == i.getModX() || p.getY() == i.getModY()) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
for (BlockFace i : BlockFace.values()) {
|
||||
if (p.getX() == i.getModX() || p.getY() == i.getModY() || p.getZ() == i.getModZ()) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Angle the vector in a self relative direction
|
||||
*
|
||||
* @param v the initial direction
|
||||
* @param amt the amount to shift in the direction
|
||||
* @return the shifted direction
|
||||
*/
|
||||
public static Vector angleLeft(Vector v, float amt) {
|
||||
Location l = new Location(Bukkit.getWorlds().get(0), 0, 0, 0);
|
||||
l.setDirection(v);
|
||||
float y = l.getYaw();
|
||||
float p = l.getPitch();
|
||||
CDou cy = new CDou(360);
|
||||
CDou cp = new CDou(180);
|
||||
cy.set(y);
|
||||
cp.set(p);
|
||||
cy.sub(amt);
|
||||
l.setYaw((float) cy.get());
|
||||
l.setPitch((float) cp.get());
|
||||
|
||||
return l.getDirection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Angle the vector in a self relative direction
|
||||
*
|
||||
* @param v the initial direction
|
||||
* @param amt the amount to shift in the direction
|
||||
* @return the shifted direction
|
||||
*/
|
||||
public static Vector angleRight(Vector v, float amt) {
|
||||
Location l = new Location(Bukkit.getWorlds().get(0), 0, 0, 0);
|
||||
l.setDirection(v);
|
||||
float y = l.getYaw();
|
||||
float p = l.getPitch();
|
||||
CDou cy = new CDou(360);
|
||||
CDou cp = new CDou(180);
|
||||
cy.set(y);
|
||||
cp.set(p);
|
||||
cy.add(amt);
|
||||
l.setYaw((float) cy.get());
|
||||
l.setPitch((float) cp.get());
|
||||
|
||||
return l.getDirection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Angle the vector in a self relative direction
|
||||
*
|
||||
* @param v the initial direction
|
||||
* @param amt the amount to shift in the direction
|
||||
* @return the shifted direction
|
||||
*/
|
||||
public static Vector angleUp(Vector v, float amt) {
|
||||
Location l = new Location(Bukkit.getWorlds().get(0), 0, 0, 0);
|
||||
l.setDirection(v);
|
||||
float y = l.getYaw();
|
||||
float p = l.getPitch();
|
||||
CDou cy = new CDou(360);
|
||||
cy.set(y);
|
||||
l.setYaw((float) cy.get());
|
||||
l.setPitch(Math.max(-90, p - amt));
|
||||
|
||||
return l.getDirection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Angle the vector in a self relative direction
|
||||
*
|
||||
* @param v the initial direction
|
||||
* @param amt the amount to shift in the direction
|
||||
* @return the shifted direction
|
||||
*/
|
||||
public static Vector angleDown(Vector v, float amt) {
|
||||
Location l = new Location(Bukkit.getWorlds().get(0), 0, 0, 0);
|
||||
l.setDirection(v);
|
||||
float y = l.getYaw();
|
||||
float p = l.getPitch();
|
||||
CDou cy = new CDou(360);
|
||||
cy.set(y);
|
||||
l.setYaw((float) cy.get());
|
||||
l.setPitch(Math.min(90, p + amt));
|
||||
|
||||
return l.getDirection();
|
||||
}
|
||||
|
||||
/**
|
||||
* (clone) Force normalize the vector into three points, 1, 0, or -1. If the
|
||||
* value is > 0.333 (1) if the value is less than -0.333 (-1) else 0
|
||||
*
|
||||
* @param direction the direction
|
||||
* @return the vector
|
||||
*/
|
||||
public static Vector triNormalize(Vector direction) {
|
||||
Vector v = direction.clone();
|
||||
v.normalize();
|
||||
|
||||
if (v.getX() > 0.333) {
|
||||
v.setX(1);
|
||||
} else if (v.getX() < -0.333) {
|
||||
v.setX(-1);
|
||||
} else {
|
||||
v.setX(0);
|
||||
}
|
||||
|
||||
if (v.getY() > 0.333) {
|
||||
v.setY(1);
|
||||
} else if (v.getY() < -0.333) {
|
||||
v.setY(-1);
|
||||
} else {
|
||||
v.setY(0);
|
||||
}
|
||||
|
||||
if (v.getZ() > 0.333) {
|
||||
v.setZ(1);
|
||||
} else if (v.getZ() < -0.333) {
|
||||
v.setZ(-1);
|
||||
} else {
|
||||
v.setZ(0);
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user