From 0b12f7ddeb869c7ac980205286abe9318a597e7c Mon Sep 17 00:00:00 2001 From: jannetty Date: Mon, 20 Oct 2025 11:26:27 -0700 Subject: [PATCH 01/12] adding ability to determine offset in the frame of the Apical axis in PottsLocation2D --- .../potts/env/location/PottsLocation2D.java | 53 +++++++++++ .../potts/env/location/Location3DTest.java | 89 +++++++++++++++++++ 2 files changed, 142 insertions(+) diff --git a/src/arcade/potts/env/location/PottsLocation2D.java b/src/arcade/potts/env/location/PottsLocation2D.java index 0a8fcc986..c00577611 100644 --- a/src/arcade/potts/env/location/PottsLocation2D.java +++ b/src/arcade/potts/env/location/PottsLocation2D.java @@ -1,7 +1,10 @@ package arcade.potts.env.location; import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; import java.util.HashMap; +import arcade.core.util.Vector; import static arcade.potts.util.PottsEnums.Direction; /** Concrete implementation of {@link PottsLocation} for 2D. */ @@ -64,4 +67,54 @@ Direction getSlice(Direction direction, HashMap diameters) { ArrayList getSelected(Voxel focus, double n) { return Location2D.getSelected(voxels, focus, n); } + + /* + * Gets the voxel through which a plane of division will pass from percentage + * offsets along the locations's X and Y axes with the provided apicalAxis set as + * the Y axis. + * + * @param offsets the percent offsets along the location's X and Y axes + * @param apicalAxis the axis considered to be pointing up along the Y axis + * @return the voxel through which the plane of division will pass + */ + public Voxel getOffsetInApicalFrame2D(ArrayList offsets, Vector apicalAxis) { + if (voxels.isEmpty()) { + return null; + } + if (offsets == null || offsets.size() != 2) { + throw new IllegalArgumentException("Offsets must be 2 integers."); + } + + // Normalize axes + Vector yAxis = Vector.normalizeVector(apicalAxis); + Vector xAxis = Vector.normalizeVector(new Vector(apicalAxis.getY(), -apicalAxis.getX(), 0)); + + // Project voxels onto apical axis and group by rounded projection + HashMap> apicalBands = new HashMap<>(); + ArrayList apicalKeys = new ArrayList<>(); + + for (Voxel v : voxels) { + Vector pos = new Vector(v.x, v.y, 0); + double apicalProj = Vector.dotProduct(pos, yAxis); + int roundedProj = (int) Math.round(apicalProj); + apicalBands.computeIfAbsent(roundedProj, k -> new ArrayList<>()).add(v); + apicalKeys.add(roundedProj); + } + + // Sort apical keys and choose percentile + Collections.sort(apicalKeys); + int yIndex = + Math.min( + apicalKeys.size() - 1, + (int) ((offsets.get(1) / 100.0) * apicalKeys.size())); + int targetApicalKey = apicalKeys.get(yIndex); + + ArrayList band = apicalBands.get(targetApicalKey); + if (band == null || band.isEmpty()) return null; + // Project to orthogonal axis within the band and sort + band.sort( + Comparator.comparingDouble(v -> Vector.dotProduct(new Vector(v.x, v.y, 0), xAxis))); + int xIndex = Math.min(band.size() - 1, (int) ((offsets.get(0) / 100.0) * band.size())); + return band.get(xIndex); + } } diff --git a/test/arcade/potts/env/location/Location3DTest.java b/test/arcade/potts/env/location/Location3DTest.java index 66aeeb547..85efebb06 100644 --- a/test/arcade/potts/env/location/Location3DTest.java +++ b/test/arcade/potts/env/location/Location3DTest.java @@ -4,6 +4,7 @@ import java.util.HashMap; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import arcade.core.util.Vector; import static org.junit.jupiter.api.Assertions.*; import static arcade.core.ARCADETestUtilities.*; import static arcade.potts.env.location.Voxel.VOXEL_COMPARATOR; @@ -1209,4 +1210,92 @@ public void getSelected_minSizeLocations_returnsList() { assertEquals(selected.size(), 0); } + + @Test + public void getVolumeInformedOffsetInApicalFrame2D_returnsExpectedVoxel_atCenter() { + ArrayList voxels = new ArrayList<>(); + // 3x3 grid centered at (0,0) + for (int x = -1; x <= 1; x++) { + for (int y = -1; y <= 1; y++) { + voxels.add(new Voxel(x, y, 0)); + } + } + PottsLocation2D loc = new PottsLocation2D(voxels); + + Vector apicalAxis = new Vector(0, 1, 0); // Y-axis + ArrayList offsets = new ArrayList<>(); + offsets.add(50); // middle of X axis + offsets.add(50); // middle of Y axis + + Voxel result = loc.getOffsetInApicalFrame2D(offsets, apicalAxis); + assertEquals(new Voxel(0, 0, 0), result); + } + + @Test + public void getVolumeInformedOffsetInApicalFrame2D_returnsExpectedVoxel_upperRight() { + ArrayList voxels = new ArrayList<>(); + for (int x = 0; x <= 4; x++) { + for (int y = 0; y <= 4; y++) { + voxels.add(new Voxel(x, y, 0)); + } + } + PottsLocation2D loc = new PottsLocation2D(voxels); + + Vector apicalAxis = new Vector(0, 1, 0); // Y-axis + ArrayList offsets = new ArrayList<>(); + offsets.add(100); // far right of X axis + offsets.add(100); // top of Y axis + + Voxel result = loc.getOffsetInApicalFrame2D(offsets, apicalAxis); + assertEquals(new Voxel(4, 4, 0), result); + } + + @Test + public void getVolumeInformedOffsetInApicalFrame2D_emptyVoxels_returnsNull() { + PottsLocation2D loc = new PottsLocation2D(new ArrayList<>()); + + Vector apicalAxis = new Vector(1, 0, 0); + ArrayList offsets = new ArrayList<>(); + offsets.add(50); + offsets.add(50); + + Voxel result = loc.getOffsetInApicalFrame2D(offsets, apicalAxis); + assertNull(result); + } + + @Test + public void getVolumeInformedOffsetInApicalFrame2D_invalidOffset_throwsException() { + ArrayList voxels = new ArrayList<>(); + voxels.add(new Voxel(0, 0, 0)); + PottsLocation2D loc = new PottsLocation2D(voxels); + + Vector apicalAxis = new Vector(1, 0, 0); + + ArrayList badOffset = new ArrayList<>(); + badOffset.add(50); // only one element + + assertThrows( + IllegalArgumentException.class, + () -> { + loc.getOffsetInApicalFrame2D(badOffset, apicalAxis); + }); + } + + @Test + public void getVolumeInformedOffsetInApicalFrame2D_nonOrthogonalAxis_returnsExpected() { + ArrayList voxels = new ArrayList<>(); + voxels.add(new Voxel(0, 0, 0)); + voxels.add(new Voxel(1, 1, 0)); + voxels.add(new Voxel(2, 2, 0)); + voxels.add(new Voxel(3, 3, 0)); + PottsLocation2D loc = new PottsLocation2D(voxels); + + Vector apicalAxis = new Vector(1, 1, 0); // diagonal + ArrayList offsets = new ArrayList<>(); + offsets.add(0); // lowest orthogonal axis + offsets.add(100); // farthest along apical + + Voxel result = loc.getOffsetInApicalFrame2D(offsets, apicalAxis); + assertEquals(new Voxel(3, 3, 0), result); + } } From d3bd6f686cd2378452f7d16198f6f8011c3ca613 Mon Sep 17 00:00:00 2001 From: jannetty Date: Mon, 20 Oct 2025 11:36:24 -0700 Subject: [PATCH 02/12] moving tests into correct place --- .../potts/env/location/PottsLocation2D.java | 11 +-- .../potts/env/location/Location3DTest.java | 89 ------------------- .../env/location/PottsLocation2DTest.java | 89 +++++++++++++++++++ 3 files changed, 95 insertions(+), 94 deletions(-) diff --git a/src/arcade/potts/env/location/PottsLocation2D.java b/src/arcade/potts/env/location/PottsLocation2D.java index c00577611..a94e41244 100644 --- a/src/arcade/potts/env/location/PottsLocation2D.java +++ b/src/arcade/potts/env/location/PottsLocation2D.java @@ -68,10 +68,9 @@ ArrayList getSelected(Voxel focus, double n) { return Location2D.getSelected(voxels, focus, n); } - /* - * Gets the voxel through which a plane of division will pass from percentage - * offsets along the locations's X and Y axes with the provided apicalAxis set as - * the Y axis. + /** + * Gets the voxel through which a plane of division will pass from percentage offsets along the + * locations's X and Y axes with the provided apicalAxis set as the Y axis. * * @param offsets the percent offsets along the location's X and Y axes * @param apicalAxis the axis considered to be pointing up along the Y axis @@ -110,7 +109,9 @@ public Voxel getOffsetInApicalFrame2D(ArrayList offsets, Vector apicalA int targetApicalKey = apicalKeys.get(yIndex); ArrayList band = apicalBands.get(targetApicalKey); - if (band == null || band.isEmpty()) return null; + if (band == null || band.isEmpty()) { + return null; + } // Project to orthogonal axis within the band and sort band.sort( Comparator.comparingDouble(v -> Vector.dotProduct(new Vector(v.x, v.y, 0), xAxis))); diff --git a/test/arcade/potts/env/location/Location3DTest.java b/test/arcade/potts/env/location/Location3DTest.java index 85efebb06..66aeeb547 100644 --- a/test/arcade/potts/env/location/Location3DTest.java +++ b/test/arcade/potts/env/location/Location3DTest.java @@ -4,7 +4,6 @@ import java.util.HashMap; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import arcade.core.util.Vector; import static org.junit.jupiter.api.Assertions.*; import static arcade.core.ARCADETestUtilities.*; import static arcade.potts.env.location.Voxel.VOXEL_COMPARATOR; @@ -1210,92 +1209,4 @@ public void getSelected_minSizeLocations_returnsList() { assertEquals(selected.size(), 0); } - - @Test - public void getVolumeInformedOffsetInApicalFrame2D_returnsExpectedVoxel_atCenter() { - ArrayList voxels = new ArrayList<>(); - // 3x3 grid centered at (0,0) - for (int x = -1; x <= 1; x++) { - for (int y = -1; y <= 1; y++) { - voxels.add(new Voxel(x, y, 0)); - } - } - PottsLocation2D loc = new PottsLocation2D(voxels); - - Vector apicalAxis = new Vector(0, 1, 0); // Y-axis - ArrayList offsets = new ArrayList<>(); - offsets.add(50); // middle of X axis - offsets.add(50); // middle of Y axis - - Voxel result = loc.getOffsetInApicalFrame2D(offsets, apicalAxis); - assertEquals(new Voxel(0, 0, 0), result); - } - - @Test - public void getVolumeInformedOffsetInApicalFrame2D_returnsExpectedVoxel_upperRight() { - ArrayList voxels = new ArrayList<>(); - for (int x = 0; x <= 4; x++) { - for (int y = 0; y <= 4; y++) { - voxels.add(new Voxel(x, y, 0)); - } - } - PottsLocation2D loc = new PottsLocation2D(voxels); - - Vector apicalAxis = new Vector(0, 1, 0); // Y-axis - ArrayList offsets = new ArrayList<>(); - offsets.add(100); // far right of X axis - offsets.add(100); // top of Y axis - - Voxel result = loc.getOffsetInApicalFrame2D(offsets, apicalAxis); - assertEquals(new Voxel(4, 4, 0), result); - } - - @Test - public void getVolumeInformedOffsetInApicalFrame2D_emptyVoxels_returnsNull() { - PottsLocation2D loc = new PottsLocation2D(new ArrayList<>()); - - Vector apicalAxis = new Vector(1, 0, 0); - ArrayList offsets = new ArrayList<>(); - offsets.add(50); - offsets.add(50); - - Voxel result = loc.getOffsetInApicalFrame2D(offsets, apicalAxis); - assertNull(result); - } - - @Test - public void getVolumeInformedOffsetInApicalFrame2D_invalidOffset_throwsException() { - ArrayList voxels = new ArrayList<>(); - voxels.add(new Voxel(0, 0, 0)); - PottsLocation2D loc = new PottsLocation2D(voxels); - - Vector apicalAxis = new Vector(1, 0, 0); - - ArrayList badOffset = new ArrayList<>(); - badOffset.add(50); // only one element - - assertThrows( - IllegalArgumentException.class, - () -> { - loc.getOffsetInApicalFrame2D(badOffset, apicalAxis); - }); - } - - @Test - public void getVolumeInformedOffsetInApicalFrame2D_nonOrthogonalAxis_returnsExpected() { - ArrayList voxels = new ArrayList<>(); - voxels.add(new Voxel(0, 0, 0)); - voxels.add(new Voxel(1, 1, 0)); - voxels.add(new Voxel(2, 2, 0)); - voxels.add(new Voxel(3, 3, 0)); - PottsLocation2D loc = new PottsLocation2D(voxels); - - Vector apicalAxis = new Vector(1, 1, 0); // diagonal - ArrayList offsets = new ArrayList<>(); - offsets.add(0); // lowest orthogonal axis - offsets.add(100); // farthest along apical - - Voxel result = loc.getOffsetInApicalFrame2D(offsets, apicalAxis); - assertEquals(new Voxel(3, 3, 0), result); - } } diff --git a/test/arcade/potts/env/location/PottsLocation2DTest.java b/test/arcade/potts/env/location/PottsLocation2DTest.java index 81f861ab3..6015f8b87 100644 --- a/test/arcade/potts/env/location/PottsLocation2DTest.java +++ b/test/arcade/potts/env/location/PottsLocation2DTest.java @@ -4,6 +4,7 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import ec.util.MersenneTwisterFast; +import arcade.core.util.Vector; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; import static arcade.potts.env.location.Voxel.VOXEL_COMPARATOR; @@ -278,4 +279,92 @@ public void split_balanceableLocationRandomOne_returnsList() { assertEquals(locVoxels, loc.voxels); assertEquals(splitVoxels, split.voxels); } + + @Test + public void getVolumeInformedOffsetInApicalFrame2D_returnsExpectedVoxel_atCenter() { + ArrayList voxels = new ArrayList<>(); + // 3x3 grid centered at (0,0) + for (int x = -1; x <= 1; x++) { + for (int y = -1; y <= 1; y++) { + voxels.add(new Voxel(x, y, 0)); + } + } + PottsLocation2D loc = new PottsLocation2D(voxels); + + Vector apicalAxis = new Vector(0, 1, 0); // Y-axis + ArrayList offsets = new ArrayList<>(); + offsets.add(50); // middle of X axis + offsets.add(50); // middle of Y axis + + Voxel result = loc.getOffsetInApicalFrame2D(offsets, apicalAxis); + assertEquals(new Voxel(0, 0, 0), result); + } + + @Test + public void getVolumeInformedOffsetInApicalFrame2D_returnsExpectedVoxel_upperRight() { + ArrayList voxels = new ArrayList<>(); + for (int x = 0; x <= 4; x++) { + for (int y = 0; y <= 4; y++) { + voxels.add(new Voxel(x, y, 0)); + } + } + PottsLocation2D loc = new PottsLocation2D(voxels); + + Vector apicalAxis = new Vector(0, 1, 0); // Y-axis + ArrayList offsets = new ArrayList<>(); + offsets.add(100); // far right of X axis + offsets.add(100); // top of Y axis + + Voxel result = loc.getOffsetInApicalFrame2D(offsets, apicalAxis); + assertEquals(new Voxel(4, 4, 0), result); + } + + @Test + public void getVolumeInformedOffsetInApicalFrame2D_emptyVoxels_returnsNull() { + PottsLocation2D loc = new PottsLocation2D(new ArrayList<>()); + + Vector apicalAxis = new Vector(1, 0, 0); + ArrayList offsets = new ArrayList<>(); + offsets.add(50); + offsets.add(50); + + Voxel result = loc.getOffsetInApicalFrame2D(offsets, apicalAxis); + assertNull(result); + } + + @Test + public void getVolumeInformedOffsetInApicalFrame2D_invalidOffset_throwsException() { + ArrayList voxels = new ArrayList<>(); + voxels.add(new Voxel(0, 0, 0)); + PottsLocation2D loc = new PottsLocation2D(voxels); + + Vector apicalAxis = new Vector(1, 0, 0); + + ArrayList badOffset = new ArrayList<>(); + badOffset.add(50); // only one element + + assertThrows( + IllegalArgumentException.class, + () -> { + loc.getOffsetInApicalFrame2D(badOffset, apicalAxis); + }); + } + + @Test + public void getVolumeInformedOffsetInApicalFrame2D_nonOrthogonalAxis_returnsExpected() { + ArrayList voxels = new ArrayList<>(); + voxels.add(new Voxel(0, 0, 0)); + voxels.add(new Voxel(1, 1, 0)); + voxels.add(new Voxel(2, 2, 0)); + voxels.add(new Voxel(3, 3, 0)); + PottsLocation2D loc = new PottsLocation2D(voxels); + + Vector apicalAxis = new Vector(1, 1, 0); // diagonal + ArrayList offsets = new ArrayList<>(); + offsets.add(0); // lowest orthogonal axis + offsets.add(100); // farthest along apical + + Voxel result = loc.getOffsetInApicalFrame2D(offsets, apicalAxis); + assertEquals(new Voxel(3, 3, 0), result); + } } From 75382f3d8bcbbe1c0e7f69065831dec324a3c3bd Mon Sep 17 00:00:00 2001 From: jannetty Date: Mon, 20 Oct 2025 11:38:48 -0700 Subject: [PATCH 03/12] updated test name to reflect function name --- .../arcade/potts/env/location/PottsLocation2DTest.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/arcade/potts/env/location/PottsLocation2DTest.java b/test/arcade/potts/env/location/PottsLocation2DTest.java index 6015f8b87..838e3937e 100644 --- a/test/arcade/potts/env/location/PottsLocation2DTest.java +++ b/test/arcade/potts/env/location/PottsLocation2DTest.java @@ -281,7 +281,7 @@ public void split_balanceableLocationRandomOne_returnsList() { } @Test - public void getVolumeInformedOffsetInApicalFrame2D_returnsExpectedVoxel_atCenter() { + public void getOffsetInApicalFrame2D_returnsExpectedVoxel_atCenter() { ArrayList voxels = new ArrayList<>(); // 3x3 grid centered at (0,0) for (int x = -1; x <= 1; x++) { @@ -301,7 +301,7 @@ public void getVolumeInformedOffsetInApicalFrame2D_returnsExpectedVoxel_atCenter } @Test - public void getVolumeInformedOffsetInApicalFrame2D_returnsExpectedVoxel_upperRight() { + public void getOffsetInApicalFrame2D_returnsExpectedVoxel_upperRight() { ArrayList voxels = new ArrayList<>(); for (int x = 0; x <= 4; x++) { for (int y = 0; y <= 4; y++) { @@ -320,7 +320,7 @@ public void getVolumeInformedOffsetInApicalFrame2D_returnsExpectedVoxel_upperRig } @Test - public void getVolumeInformedOffsetInApicalFrame2D_emptyVoxels_returnsNull() { + public void getOffsetInApicalFrame2D_emptyVoxels_returnsNull() { PottsLocation2D loc = new PottsLocation2D(new ArrayList<>()); Vector apicalAxis = new Vector(1, 0, 0); @@ -333,7 +333,7 @@ public void getVolumeInformedOffsetInApicalFrame2D_emptyVoxels_returnsNull() { } @Test - public void getVolumeInformedOffsetInApicalFrame2D_invalidOffset_throwsException() { + public void getOffsetInApicalFrame2D_invalidOffset_throwsException() { ArrayList voxels = new ArrayList<>(); voxels.add(new Voxel(0, 0, 0)); PottsLocation2D loc = new PottsLocation2D(voxels); @@ -351,7 +351,7 @@ public void getVolumeInformedOffsetInApicalFrame2D_invalidOffset_throwsException } @Test - public void getVolumeInformedOffsetInApicalFrame2D_nonOrthogonalAxis_returnsExpected() { + public void getOffsetInApicalFrame2D_nonOrthogonalAxis_returnsExpected() { ArrayList voxels = new ArrayList<>(); voxels.add(new Voxel(0, 0, 0)); voxels.add(new Voxel(1, 1, 0)); From df911dc30c808d027c4f9a530a05ef515ac6c5da Mon Sep 17 00:00:00 2001 From: jannetty Date: Mon, 20 Oct 2025 11:40:33 -0700 Subject: [PATCH 04/12] updating test titles --- test/arcade/potts/env/location/PottsLocation2DTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/arcade/potts/env/location/PottsLocation2DTest.java b/test/arcade/potts/env/location/PottsLocation2DTest.java index 838e3937e..25396de49 100644 --- a/test/arcade/potts/env/location/PottsLocation2DTest.java +++ b/test/arcade/potts/env/location/PottsLocation2DTest.java @@ -281,7 +281,7 @@ public void split_balanceableLocationRandomOne_returnsList() { } @Test - public void getOffsetInApicalFrame2D_returnsExpectedVoxel_atCenter() { + public void getOffsetInApicalFrame2D_offsetAtCenter_returnsExpectedVoxel() { ArrayList voxels = new ArrayList<>(); // 3x3 grid centered at (0,0) for (int x = -1; x <= 1; x++) { @@ -301,7 +301,7 @@ public void getOffsetInApicalFrame2D_returnsExpectedVoxel_atCenter() { } @Test - public void getOffsetInApicalFrame2D_returnsExpectedVoxel_upperRight() { + public void getOffsetInApicalFrame2D_offsetUpperRight_returnsExpectedVoxel() { ArrayList voxels = new ArrayList<>(); for (int x = 0; x <= 4; x++) { for (int y = 0; y <= 4; y++) { From ba31c8545998eadcdc745afa452a1c7ea2fb44f6 Mon Sep 17 00:00:00 2001 From: jannetty Date: Mon, 20 Oct 2025 11:45:30 -0700 Subject: [PATCH 05/12] updating docstring --- src/arcade/potts/env/location/PottsLocation2D.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/arcade/potts/env/location/PottsLocation2D.java b/src/arcade/potts/env/location/PottsLocation2D.java index a94e41244..166b153c3 100644 --- a/src/arcade/potts/env/location/PottsLocation2D.java +++ b/src/arcade/potts/env/location/PottsLocation2D.java @@ -69,8 +69,8 @@ ArrayList getSelected(Voxel focus, double n) { } /** - * Gets the voxel through which a plane of division will pass from percentage offsets along the - * locations's X and Y axes with the provided apicalAxis set as the Y axis. + * Gets the voxel at specified percentage offsets along the location's X and + * Y axes with the provided apicalAxis considered to be pointing up the Y axis. * * @param offsets the percent offsets along the location's X and Y axes * @param apicalAxis the axis considered to be pointing up along the Y axis From 9a76cf1972c367f15c3f33e5e5085bc9d50c50f0 Mon Sep 17 00:00:00 2001 From: jannetty Date: Mon, 20 Oct 2025 11:46:06 -0700 Subject: [PATCH 06/12] formatting --- src/arcade/potts/env/location/PottsLocation2D.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/arcade/potts/env/location/PottsLocation2D.java b/src/arcade/potts/env/location/PottsLocation2D.java index 166b153c3..102a60011 100644 --- a/src/arcade/potts/env/location/PottsLocation2D.java +++ b/src/arcade/potts/env/location/PottsLocation2D.java @@ -69,8 +69,8 @@ ArrayList getSelected(Voxel focus, double n) { } /** - * Gets the voxel at specified percentage offsets along the location's X and - * Y axes with the provided apicalAxis considered to be pointing up the Y axis. + * Gets the voxel at specified percentage offsets along the location's X and Y axes with the + * provided apicalAxis considered to be pointing up the Y axis. * * @param offsets the percent offsets along the location's X and Y axes * @param apicalAxis the axis considered to be pointing up along the Y axis From 0b60fc6fe56664f076f347d77e9e42b8d3b0c514 Mon Sep 17 00:00:00 2001 From: jannetty Date: Thu, 30 Oct 2025 10:01:49 -0700 Subject: [PATCH 07/12] adding getOffsetInApicalFrame to PottsLocation --- src/arcade/potts/env/location/PottsLocation.java | 13 +++++++++++++ src/arcade/potts/env/location/PottsLocation2D.java | 3 ++- src/arcade/potts/env/location/PottsLocation3D.java | 8 ++++++++ src/arcade/potts/env/location/PottsLocations.java | 8 ++++++++ .../potts/env/location/PottsLocations2D.java | 9 +++++++++ .../potts/env/location/PottsLocations3D.java | 2 ++ .../potts/env/location/PottsLocation2DTest.java | 10 +++++----- .../potts/env/location/PottsLocation3DTest.java | 13 +++++++++++++ .../potts/env/location/PottsLocationTest.java | 5 +++++ .../potts/env/location/PottsLocationsTest.java | 14 ++++++++++++++ 10 files changed, 79 insertions(+), 6 deletions(-) diff --git a/src/arcade/potts/env/location/PottsLocation.java b/src/arcade/potts/env/location/PottsLocation.java index ddb5b1d94..1fdba5468 100644 --- a/src/arcade/potts/env/location/PottsLocation.java +++ b/src/arcade/potts/env/location/PottsLocation.java @@ -10,6 +10,9 @@ import arcade.core.env.location.LocationContainer; import arcade.core.util.Plane; import arcade.core.util.Utilities; +import arcade.core.util.Vector; +import arcade.potts.util.PottsEnums.Direction; +import arcade.potts.util.PottsEnums.Region; import static arcade.potts.util.PottsEnums.Direction; import static arcade.potts.util.PottsEnums.Region; @@ -605,6 +608,16 @@ void updateCenter(int x, int y, int z, int change) { */ abstract ArrayList getSelected(Voxel focus, double n); + /** + * Gets the voxel at specified percentage offsets along the location's axes with the provided + * ApicalAxis considered to be pointing up the Y axis + * + * @param offsets the percent offsets along the location's axes + * @param apicalAxis the axis considered to be pointing up along the Y axis + * @return the voxel at the specified offset in the frame of the apical axis + */ + abstract Voxel getOffsetInApicalFrame(ArrayList offsets, Vector apicalAxis); + /** * Gets the direction of the slice orthagonal to the direction with the smallest diameter. * diff --git a/src/arcade/potts/env/location/PottsLocation2D.java b/src/arcade/potts/env/location/PottsLocation2D.java index 102a60011..a6828bc69 100644 --- a/src/arcade/potts/env/location/PottsLocation2D.java +++ b/src/arcade/potts/env/location/PottsLocation2D.java @@ -76,7 +76,8 @@ ArrayList getSelected(Voxel focus, double n) { * @param apicalAxis the axis considered to be pointing up along the Y axis * @return the voxel through which the plane of division will pass */ - public Voxel getOffsetInApicalFrame2D(ArrayList offsets, Vector apicalAxis) { + @Override + public Voxel getOffsetInApicalFrame(ArrayList offsets, Vector apicalAxis) { if (voxels.isEmpty()) { return null; } diff --git a/src/arcade/potts/env/location/PottsLocation3D.java b/src/arcade/potts/env/location/PottsLocation3D.java index b9e9c1aec..c6ad40cd1 100644 --- a/src/arcade/potts/env/location/PottsLocation3D.java +++ b/src/arcade/potts/env/location/PottsLocation3D.java @@ -2,6 +2,8 @@ import java.util.ArrayList; import java.util.HashMap; +import arcade.core.util.Vector; +import arcade.potts.util.PottsEnums.Direction; import static arcade.potts.util.PottsEnums.Direction; /** Concrete implementation of {@link PottsLocation} for 3D. */ @@ -64,4 +66,10 @@ Direction getSlice(Direction direction, HashMap diameters) { ArrayList getSelected(Voxel focus, double n) { return Location3D.getSelected(voxels, focus, n); } + + @Override + Voxel getOffsetInApicalFrame(ArrayList offsets, Vector apicalAxis) { + throw new UnsupportedOperationException( + "getOffsetInApicalFrame is not implemented for PottsLocation3D"); + } } diff --git a/src/arcade/potts/env/location/PottsLocations.java b/src/arcade/potts/env/location/PottsLocations.java index 1b829e426..4ae66311e 100644 --- a/src/arcade/potts/env/location/PottsLocations.java +++ b/src/arcade/potts/env/location/PottsLocations.java @@ -6,6 +6,8 @@ import ec.util.MersenneTwisterFast; import arcade.core.env.location.Location; import arcade.core.env.location.LocationContainer; +import arcade.core.util.Vector; +import arcade.potts.util.PottsEnums.Region; import static arcade.potts.util.PottsEnums.Region; /** @@ -286,4 +288,10 @@ Location separateVoxels( return splitLocation; } + + @Override + Voxel getOffsetInApicalFrame(ArrayList offsets, Vector apicalAxis) { + throw new UnsupportedOperationException( + "getOffsetInApicalFrame is not implemented for PottsLocations"); + } } diff --git a/src/arcade/potts/env/location/PottsLocations2D.java b/src/arcade/potts/env/location/PottsLocations2D.java index 7877b24f9..52b5721db 100644 --- a/src/arcade/potts/env/location/PottsLocations2D.java +++ b/src/arcade/potts/env/location/PottsLocations2D.java @@ -2,6 +2,9 @@ import java.util.ArrayList; import java.util.HashMap; +import arcade.core.util.Vector; +import arcade.potts.util.PottsEnums.Direction; +import arcade.potts.util.PottsEnums.Region; import static arcade.potts.util.PottsEnums.Direction; import static arcade.potts.util.PottsEnums.Region; @@ -70,4 +73,10 @@ Direction getSlice(Direction direction, HashMap diameters) { ArrayList getSelected(Voxel focus, double n) { return Location2D.getSelected(locations.get(Region.DEFAULT).voxels, focus, n); } + + @Override + Voxel getOffsetInApicalFrame(ArrayList offsets, Vector apicalAxis) { + throw new UnsupportedOperationException( + "getOffsetInApicalFrame is not implemented for PottsLocations2D"); + } } diff --git a/src/arcade/potts/env/location/PottsLocations3D.java b/src/arcade/potts/env/location/PottsLocations3D.java index c6d0b82dc..555e25f42 100644 --- a/src/arcade/potts/env/location/PottsLocations3D.java +++ b/src/arcade/potts/env/location/PottsLocations3D.java @@ -2,6 +2,8 @@ import java.util.ArrayList; import java.util.HashMap; +import arcade.potts.util.PottsEnums.Direction; +import arcade.potts.util.PottsEnums.Region; import static arcade.potts.util.PottsEnums.Direction; import static arcade.potts.util.PottsEnums.Region; diff --git a/test/arcade/potts/env/location/PottsLocation2DTest.java b/test/arcade/potts/env/location/PottsLocation2DTest.java index 25396de49..da5d53c6a 100644 --- a/test/arcade/potts/env/location/PottsLocation2DTest.java +++ b/test/arcade/potts/env/location/PottsLocation2DTest.java @@ -296,7 +296,7 @@ public void getOffsetInApicalFrame2D_offsetAtCenter_returnsExpectedVoxel() { offsets.add(50); // middle of X axis offsets.add(50); // middle of Y axis - Voxel result = loc.getOffsetInApicalFrame2D(offsets, apicalAxis); + Voxel result = loc.getOffsetInApicalFrame(offsets, apicalAxis); assertEquals(new Voxel(0, 0, 0), result); } @@ -315,7 +315,7 @@ public void getOffsetInApicalFrame2D_offsetUpperRight_returnsExpectedVoxel() { offsets.add(100); // far right of X axis offsets.add(100); // top of Y axis - Voxel result = loc.getOffsetInApicalFrame2D(offsets, apicalAxis); + Voxel result = loc.getOffsetInApicalFrame(offsets, apicalAxis); assertEquals(new Voxel(4, 4, 0), result); } @@ -328,7 +328,7 @@ public void getOffsetInApicalFrame2D_emptyVoxels_returnsNull() { offsets.add(50); offsets.add(50); - Voxel result = loc.getOffsetInApicalFrame2D(offsets, apicalAxis); + Voxel result = loc.getOffsetInApicalFrame(offsets, apicalAxis); assertNull(result); } @@ -346,7 +346,7 @@ public void getOffsetInApicalFrame2D_invalidOffset_throwsException() { assertThrows( IllegalArgumentException.class, () -> { - loc.getOffsetInApicalFrame2D(badOffset, apicalAxis); + loc.getOffsetInApicalFrame(badOffset, apicalAxis); }); } @@ -364,7 +364,7 @@ public void getOffsetInApicalFrame2D_nonOrthogonalAxis_returnsExpected() { offsets.add(0); // lowest orthogonal axis offsets.add(100); // farthest along apical - Voxel result = loc.getOffsetInApicalFrame2D(offsets, apicalAxis); + Voxel result = loc.getOffsetInApicalFrame(offsets, apicalAxis); assertEquals(new Voxel(3, 3, 0), result); } } diff --git a/test/arcade/potts/env/location/PottsLocation3DTest.java b/test/arcade/potts/env/location/PottsLocation3DTest.java index 9b5742c41..928741174 100644 --- a/test/arcade/potts/env/location/PottsLocation3DTest.java +++ b/test/arcade/potts/env/location/PottsLocation3DTest.java @@ -4,6 +4,7 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import ec.util.MersenneTwisterFast; +import arcade.core.util.Vector; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; import static arcade.potts.env.location.Voxel.VOXEL_COMPARATOR; @@ -298,4 +299,16 @@ public void split_balanceableLocationRandomOne_returnsList() { assertEquals(locVoxels, loc.voxels); assertEquals(splitVoxels, split.voxels); } + + @Test + public void getOffsetInApicalFrame_called_raisesUnsupportedOperationException() { + { + PottsLocation3D loc = new PottsLocation3D(voxelListAB); + Vector apicalAxis = new Vector(0, 1, 0); + ArrayList offsets = new ArrayList<>(); + assertThrows( + UnsupportedOperationException.class, + () -> loc.getOffsetInApicalFrame(offsets, apicalAxis)); + } + } } diff --git a/test/arcade/potts/env/location/PottsLocationTest.java b/test/arcade/potts/env/location/PottsLocationTest.java index ef48c8f5b..00a90c1a3 100644 --- a/test/arcade/potts/env/location/PottsLocationTest.java +++ b/test/arcade/potts/env/location/PottsLocationTest.java @@ -169,6 +169,11 @@ Direction getSlice(Direction direction, HashMap diameters) { ArrayList getSelected(Voxel center, double n) { return new ArrayList<>(); } + + @Override + Voxel getOffsetInApicalFrame(ArrayList offsets, Vector apicalAxis) { + return new Voxel(0, 0, 0); + } } @Test diff --git a/test/arcade/potts/env/location/PottsLocationsTest.java b/test/arcade/potts/env/location/PottsLocationsTest.java index 6c082948a..343902f7c 100644 --- a/test/arcade/potts/env/location/PottsLocationsTest.java +++ b/test/arcade/potts/env/location/PottsLocationsTest.java @@ -6,6 +6,10 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import ec.util.MersenneTwisterFast; +import arcade.core.util.Vector; +import arcade.potts.env.location.PottsLocationTest.PottsLocationMock; +import arcade.potts.util.PottsEnums.Direction; +import arcade.potts.util.PottsEnums.Region; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; import static arcade.core.ARCADETestUtilities.*; @@ -963,4 +967,14 @@ public void separateVoxels_validListsWithRegions_updatesLists() { assertEquals(2, split.locations.get(Region.DEFAULT).voxels.size()); assertEquals(2, split.locations.get(Region.DEFAULT).voxels.size()); } + + @Test + public void getOffsetInApicalFrame_called_raisesUnsupportedOperationException() { + PottsLocationsMock loc = new PottsLocationsMock(voxelListForMultipleRegionsA); + Vector apicalAxis = new Vector(0, 1, 0); + ArrayList offsets = new ArrayList<>(); + assertThrows( + UnsupportedOperationException.class, + () -> loc.getOffsetInApicalFrame(offsets, apicalAxis)); + } } From 85e008c3cddce2e6ba898bf0b2c12c70e961d480 Mon Sep 17 00:00:00 2001 From: jannetty Date: Thu, 30 Oct 2025 10:03:06 -0700 Subject: [PATCH 08/12] removing unnecessary imports --- src/arcade/potts/env/location/PottsLocations3D.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/arcade/potts/env/location/PottsLocations3D.java b/src/arcade/potts/env/location/PottsLocations3D.java index 555e25f42..c6d0b82dc 100644 --- a/src/arcade/potts/env/location/PottsLocations3D.java +++ b/src/arcade/potts/env/location/PottsLocations3D.java @@ -2,8 +2,6 @@ import java.util.ArrayList; import java.util.HashMap; -import arcade.potts.util.PottsEnums.Direction; -import arcade.potts.util.PottsEnums.Region; import static arcade.potts.util.PottsEnums.Direction; import static arcade.potts.util.PottsEnums.Region; From 5759730a79698a8ff691aece30b5db359a46d4ab Mon Sep 17 00:00:00 2001 From: jannetty Date: Thu, 30 Oct 2025 10:07:16 -0700 Subject: [PATCH 09/12] adding null case to PottsLocation2D docstring --- src/arcade/potts/env/location/PottsLocation2D.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/arcade/potts/env/location/PottsLocation2D.java b/src/arcade/potts/env/location/PottsLocation2D.java index a6828bc69..7a63ad357 100644 --- a/src/arcade/potts/env/location/PottsLocation2D.java +++ b/src/arcade/potts/env/location/PottsLocation2D.java @@ -70,7 +70,9 @@ ArrayList getSelected(Voxel focus, double n) { /** * Gets the voxel at specified percentage offsets along the location's X and Y axes with the - * provided apicalAxis considered to be pointing up the Y axis. + * provided apicalAxis considered to be pointing up the Y axis. Returns null if this + * PottsLocation2D contains no voxels or if the offsets ArrayList provided is not 2 integers + * long. * * @param offsets the percent offsets along the location's X and Y axes * @param apicalAxis the axis considered to be pointing up along the Y axis From 3ac1371ae46329936664fc9ea81c0ebd3aac57f1 Mon Sep 17 00:00:00 2001 From: jannetty Date: Thu, 30 Oct 2025 10:08:43 -0700 Subject: [PATCH 10/12] stylecheck --- src/arcade/potts/env/location/PottsLocation.java | 2 +- src/arcade/potts/env/location/PottsLocation2D.java | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/arcade/potts/env/location/PottsLocation.java b/src/arcade/potts/env/location/PottsLocation.java index 1fdba5468..ee15838a4 100644 --- a/src/arcade/potts/env/location/PottsLocation.java +++ b/src/arcade/potts/env/location/PottsLocation.java @@ -610,7 +610,7 @@ void updateCenter(int x, int y, int z, int change) { /** * Gets the voxel at specified percentage offsets along the location's axes with the provided - * ApicalAxis considered to be pointing up the Y axis + * ApicalAxis considered to be pointing up the Y axis. * * @param offsets the percent offsets along the location's axes * @param apicalAxis the axis considered to be pointing up along the Y axis diff --git a/src/arcade/potts/env/location/PottsLocation2D.java b/src/arcade/potts/env/location/PottsLocation2D.java index 7a63ad357..f61165147 100644 --- a/src/arcade/potts/env/location/PottsLocation2D.java +++ b/src/arcade/potts/env/location/PottsLocation2D.java @@ -71,8 +71,7 @@ ArrayList getSelected(Voxel focus, double n) { /** * Gets the voxel at specified percentage offsets along the location's X and Y axes with the * provided apicalAxis considered to be pointing up the Y axis. Returns null if this - * PottsLocation2D contains no voxels or if the offsets ArrayList provided is not 2 integers - * long. + * PottsLocation2D contains no voxels. * * @param offsets the percent offsets along the location's X and Y axes * @param apicalAxis the axis considered to be pointing up along the Y axis From 1a916c84f3e2b368f9e02a528e01c833dfb1ea49 Mon Sep 17 00:00:00 2001 From: jannetty Date: Wed, 5 Nov 2025 11:19:31 -0800 Subject: [PATCH 11/12] updating checkstyle version --- .github/config/checks.xml | 5 ----- .github/workflows/lint.yml | 4 ++-- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/.github/config/checks.xml b/.github/config/checks.xml index ec6a8f485..8f1ea6cea 100644 --- a/.github/config/checks.xml +++ b/.github/config/checks.xml @@ -29,11 +29,6 @@ - - - - - diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 9bec19056..929733889 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -15,12 +15,12 @@ jobs: fetch-depth: 0 - name: Lint code base - uses: dbelyaev/action-checkstyle@v0.9.5 + uses: dbelyaev/action-checkstyle@v3.0.0 with: github_token: ${{ secrets.GITHUB_TOKEN }} reporter: github-check checkstyle_config: .github/config/checks.xml - fail_on_error: true + fail_level: error update-lint-badges: if: ${{ always() && github.ref == 'refs/heads/main' }} From 6ebb959193cf2ae5fb637b7dd671aecc205c81af Mon Sep 17 00:00:00 2001 From: jannetty Date: Wed, 5 Nov 2025 11:22:52 -0800 Subject: [PATCH 12/12] removing nessted blocks --- .../potts/env/location/PottsLocation3DTest.java | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/test/arcade/potts/env/location/PottsLocation3DTest.java b/test/arcade/potts/env/location/PottsLocation3DTest.java index 928741174..a971382d3 100644 --- a/test/arcade/potts/env/location/PottsLocation3DTest.java +++ b/test/arcade/potts/env/location/PottsLocation3DTest.java @@ -302,13 +302,11 @@ public void split_balanceableLocationRandomOne_returnsList() { @Test public void getOffsetInApicalFrame_called_raisesUnsupportedOperationException() { - { - PottsLocation3D loc = new PottsLocation3D(voxelListAB); - Vector apicalAxis = new Vector(0, 1, 0); - ArrayList offsets = new ArrayList<>(); - assertThrows( - UnsupportedOperationException.class, - () -> loc.getOffsetInApicalFrame(offsets, apicalAxis)); - } + PottsLocation3D loc = new PottsLocation3D(voxelListAB); + Vector apicalAxis = new Vector(0, 1, 0); + ArrayList offsets = new ArrayList<>(); + assertThrows( + UnsupportedOperationException.class, + () -> loc.getOffsetInApicalFrame(offsets, apicalAxis)); } }