From 5179800abc24ebf6b39761ff2e62e8134770d3b2 Mon Sep 17 00:00:00 2001 From: Elizabeth Alexander Hunt Date: Sat, 28 Feb 2026 10:34:19 -0800 Subject: Minor stress test --- core/src/main/java/coffee/liz/ecs/math/Mat2.java | 88 +++++++++++++++++++++++ core/src/main/java/coffee/liz/ecs/math/Vec2.java | 88 +++++++++++++++++++++++ core/src/main/java/coffee/liz/ecs/math/Vec2f.java | 61 ++++++++++++++++ core/src/main/java/coffee/liz/ecs/math/Vec2i.java | 65 +++++++++++++++++ 4 files changed, 302 insertions(+) create mode 100644 core/src/main/java/coffee/liz/ecs/math/Mat2.java create mode 100644 core/src/main/java/coffee/liz/ecs/math/Vec2.java create mode 100644 core/src/main/java/coffee/liz/ecs/math/Vec2f.java create mode 100644 core/src/main/java/coffee/liz/ecs/math/Vec2i.java (limited to 'core/src/main/java/coffee/liz/ecs') diff --git a/core/src/main/java/coffee/liz/ecs/math/Mat2.java b/core/src/main/java/coffee/liz/ecs/math/Mat2.java new file mode 100644 index 0000000..ed9493c --- /dev/null +++ b/core/src/main/java/coffee/liz/ecs/math/Mat2.java @@ -0,0 +1,88 @@ +package coffee.liz.ecs.math; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.function.Supplier; + +public final class Mat2 { + private Mat2() { + } + + /** + * Initializes a mutable 2d matrix of given type. + * + * @param dimensions + * the dimensions + * @param constructor + * the constructor + * @return row-indexed 2d matrix of {@param dimensions} + */ + public static List> init(final Vec2 dimensions, final Function, T> constructor) { + final List> rows = new ArrayList<>(); + for (int y = 0; y < dimensions.getY(); y++) { + final List row = new ArrayList<>(dimensions.getX()); + for (int x = 0; x < dimensions.getX(); x++) + row.add(constructor.apply(Vec2i.builder().y(y).x(x).build())); + rows.add(row); + } + return rows; + } + + /** + * Convolves a {@link Convolver} across a matrix reaching neighbors around the + * grid like a torus. + * + * @param mat + * is the row-indexed 2d matrix to convolve. + * @param axes + * are the x/y major/minor axes. + * @param init + * is the initial value of the convolution. + * @param convolver + * is the {@link Convolver}. + * @param finalReduction + * to apply after {@param convolver}. + * @return result of {@param convolver} applied along axes at each cell. + * @param + * is the type of the matrix to convolve. + * @param + * is the type of the resulting type of each convolution. + */ + public static List> convolveTorus(final List> mat, final Vec2 axes, + final Supplier init, final Convolver convolver, final BiFunction finalReduction) { + final List> rows = new ArrayList<>(); + for (int y = 0; y < mat.size(); y++) { + final List row = new ArrayList<>(mat.get(y).size()); + for (int x = 0; x < mat.get(y).size(); x++) { + final T center = mat.get(y).get(x); + R result = init.get(); + for (int dy = -axes.getY(); dy <= axes.getY(); dy++) { + final int ry = Math.floorMod(y + dy, mat.size()); + for (int dx = -axes.getX(); dx <= axes.getX(); dx++) { + final int rx = Math.floorMod(x + dx, mat.get(ry).size()); + result = convolver.convolve(mat.get(ry).get(rx), Vec2i.builder().x(dx).y(dy).build(), result); + } + } + row.add(result); + } + rows.add(row); + } + + final List> reductions = new ArrayList<>(); + for (int y = 0; y < mat.size(); y++) { + final List reduction = new ArrayList<>(mat.get(y).size()); + for (int x = 0; x < mat.get(y).size(); x++) { + reduction.add(finalReduction.apply(mat.get(y).get(x), rows.get(y).get(x))); + } + reductions.add(reduction); + } + return reductions; + } + + @FunctionalInterface + public interface Convolver { + R convolve(final T center, final Vec2 rel, final R reduction); + } +} diff --git a/core/src/main/java/coffee/liz/ecs/math/Vec2.java b/core/src/main/java/coffee/liz/ecs/math/Vec2.java new file mode 100644 index 0000000..dde6e51 --- /dev/null +++ b/core/src/main/java/coffee/liz/ecs/math/Vec2.java @@ -0,0 +1,88 @@ +package coffee.liz.ecs.math; + +import java.util.function.Function; + +/** + * Cartesian vectors. + * + * @param + * the numeric type of vector components + */ +public interface Vec2 { + /** + * @return the x coordinate + */ + T getX(); + + /** + * @return the y coordinate + */ + T getY(); + + /** + * Adds another vector to this vector. + * + * @param other + * the vector to add + * @return a new vector with the result + */ + Vec2 plus(final Vec2 other); + + /** + * Subtracts another vector from this vector. + * + * @param other + * the vector to subtract + * @return a new vector with the result + */ + Vec2 minus(final Vec2 other); + + /** + * Scales this vector by the given factors. + * + * @param scaleX + * the x scale factor + * @param scaleY + * the y scale factor + * @return a new scaled vector + */ + Vec2 scale(final T scaleX, final T scaleY); + + /** + * Scales this vector by the given vector. + * + * @param scale + * scale vec. + * @return a new scaled vector + */ + default Vec2 scale(final Vec2 scale) { + return scale(scale.getX(), scale.getY()); + } + + /** + * Length of the vector. + * + * @return length. + */ + float length(); + + /** + * @return Vec2 components of {@link Vec2} + */ + Vec2 intValue(); + + /** + * @return Vec2 components of {@link Vec2} + */ + Vec2 floatValue(); + + /** + * @param xTransform + * transform of x component. + * @param yTransform + * transform of y component. + * @return transformed vec applying {@param xTransform} to x component, + * {@param yTransform} to y component. + */ + Vec2 transform(final Function xTransform, final Function yTransform); +} diff --git a/core/src/main/java/coffee/liz/ecs/math/Vec2f.java b/core/src/main/java/coffee/liz/ecs/math/Vec2f.java new file mode 100644 index 0000000..42b73e7 --- /dev/null +++ b/core/src/main/java/coffee/liz/ecs/math/Vec2f.java @@ -0,0 +1,61 @@ +package coffee.liz.ecs.math; + +import static java.lang.Math.sqrt; + +import lombok.Builder; +import lombok.Data; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +import java.util.function.Function; + +/** Float impl of {@link Vec2}. */ +@Getter +@RequiredArgsConstructor +@Data +@Builder +public final class Vec2f implements Vec2 { + /** X coordinate. */ + private final Float x; + + /** Y coordinate. */ + private final Float y; + + @Override + public Vec2 plus(final Vec2 other) { + return new Vec2f(x + other.getX(), y + other.getY()); + } + + @Override + public Vec2 minus(final Vec2 other) { + return new Vec2f(x - other.getX(), y - other.getY()); + } + + @Override + public Vec2 scale(final Float scaleX, final Float scaleY) { + return new Vec2f(x * scaleX, y * scaleY); + } + + @Override + public float length() { + return (float) sqrt(x * x + y * y); + } + + @Override + public Vec2 floatValue() { + return this; + } + + @Override + public Vec2 transform(final Function xTransform, final Function yTransform) { + return new Vec2f(xTransform.apply(getX()), yTransform.apply(getY())); + } + + @Override + public Vec2 intValue() { + return Vec2i.builder().x(this.x.intValue()).y(this.y.intValue()).build(); + } + + /** Zero float vec */ + public static Vec2 ZERO = Vec2f.builder().x(0f).y(0f).build(); +} diff --git a/core/src/main/java/coffee/liz/ecs/math/Vec2i.java b/core/src/main/java/coffee/liz/ecs/math/Vec2i.java new file mode 100644 index 0000000..326a5df --- /dev/null +++ b/core/src/main/java/coffee/liz/ecs/math/Vec2i.java @@ -0,0 +1,65 @@ +package coffee.liz.ecs.math; + +import static java.lang.Math.sqrt; + +import lombok.Builder; +import lombok.Data; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +import java.util.function.Function; + +/** Integer impl of {@link Vec2}. */ +@Getter +@RequiredArgsConstructor +@Builder +@Data +public final class Vec2i implements Vec2 { + /** X coordinate. */ + private final Integer x; + + /** Y coordinate. */ + private final Integer y; + + @Override + public Vec2 plus(final Vec2 other) { + return new Vec2i(x + other.getX(), y + other.getY()); + } + + @Override + public Vec2 minus(final Vec2 other) { + return new Vec2i(x - other.getX(), y - other.getY()); + } + + @Override + public Vec2 scale(final Integer scaleX, final Integer scaleY) { + return new Vec2i(x * scaleX, y * scaleY); + } + + @Override + public Vec2 floatValue() { + return Vec2f.builder().x(this.x.floatValue()).y(this.y.floatValue()).build(); + } + + @Override + public Vec2 transform(final Function xTransform, + final Function yTransform) { + return new Vec2i(xTransform.apply(getX()), yTransform.apply(getY())); + } + + @Override + public Vec2 intValue() { + return this; + } + + @Override + public float length() { + return (float) sqrt(x * x + y * y); + } + + public static final Vec2 NORTH = new Vec2i(0, 1); + public static final Vec2 SOUTH = new Vec2i(0, -1); + public static final Vec2 EAST = new Vec2i(1, 0); + public static final Vec2 WEST = new Vec2i(-1, 0); + public static final Vec2 ZERO = new Vec2i(0, 0); +} -- cgit v1.2.3-70-g09d2