This is an automated email from the ASF dual-hosted git repository.

asf-gitbox-commits pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git

commit fc8a1ac943516ab477cc6b7bd495130b2138f997
Author: jsorel <[email protected]>
AuthorDate: Fri Oct 16 11:46:47 2026 +0200

    feat(Math): add Vector.swizzle and Maths.removeWithin
---
 .../apache/sis/geometries/operation/Distance.java  | 52 ++++++++++++++++++++++
 .../main/org/apache/sis/maths/Maths.java           | 32 +++++++++++++
 .../main/org/apache/sis/maths/ReadOnly.java        | 18 ++++++++
 .../org/apache/sis/maths/AbstractVectorTest.java   | 37 +++++++++++++++
 4 files changed, 139 insertions(+)

diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/operation/Distance.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/operation/Distance.java
index a12587e66f..379ede03bc 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/operation/Distance.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/operation/Distance.java
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.geometries.operation;
 
+import java.util.List;
 import org.apache.sis.geometries.Point;
 import org.apache.sis.maths.Maths;
 import org.apache.sis.maths.Vectors;
@@ -136,6 +137,57 @@ public final class Distance {
         return Vectors.dot(t,t);
     }
 
+    /**
+     * Find nearest points between two lines.
+     * Only the two first coordinates of the positions are used.
+     *
+     * @param line1Coords line 1 coordinates
+     * @param buffer1 buffer to store nearest point on line 1, of length 2
+     * @param line2Coords line 2 coordinates
+     * @param buffer2 buffer to store nearest point on line 2, of length 2
+     * @param ratio size 2, will store for each line the ratio [0..1] of the 
nearest point
+     *        between the start and end points of the segment where it is
+     * @param offset size 2, will store for each line the index of the segment 
where the nearest point is
+     * @param epsilon tolerance factor
+     */
+    public static void nearest(List<? extends Vector<?>> line1Coords, double[] 
buffer1,
+                               List<? extends Vector<?>> line2Coords, double[] 
buffer2,
+                               double[] ratio, int[] offset, double epsilon){
+
+        double distance = Double.MAX_VALUE;
+
+        final double[] tempRatio = new double[2];
+        final double[] tempC1 = new double[buffer1.length];
+        final double[] tempC2 = new double[buffer1.length];
+
+        final int nb1 = line1Coords.size()-1;
+        final int nb2 = line2Coords.size()-1;
+
+        for(int i=0;i<nb1;i++){
+            final Vector<?> s1 = line1Coords.get(i);
+            final Vector<?> e1 = line1Coords.get(i+1);
+            for(int k=0;k<nb2;k++){
+                final Vector<?> s2 = line2Coords.get(k);
+                final Vector<?> e2 = line2Coords.get(k+1);
+
+                final double dist = Math.sqrt(distanceSquare(
+                                new double[]{s1.get(0),s1.get(1)}, new 
double[]{e1.get(0),e1.get(1)}, tempC1,
+                                new double[]{s2.get(0),s2.get(1)}, new 
double[]{e2.get(0),e2.get(1)}, tempC2,
+                                tempRatio,epsilon));
+                if(dist<distance){
+                    //keep informations
+                    distance = dist;
+                    offset[0] = i;
+                    offset[1] = k;
+                    ratio[0] = tempRatio[0];
+                    ratio[1] = tempRatio[1];
+                    System.arraycopy(tempC1, 0, buffer1, 0, tempC1.length);
+                    System.arraycopy(tempC2, 0, buffer2, 0, tempC2.length);
+                }
+            }
+        }
+    }
+
     /**
      * Point to point distance.
      */
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/maths/Maths.java 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/maths/Maths.java
index f00c32484b..fb90d5880b 100644
--- a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/maths/Maths.java
+++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/maths/Maths.java
@@ -1278,4 +1278,36 @@ public final class Maths {
                 }
         }
     }
+
+    /**
+     * Remove element at index.
+     * Move elements after index by -1.
+     * Last element is set to null
+     *
+     * @param values original array
+     * @param index removed element index
+     * @return removed object
+     */
+    public static Object removeWithin(Object[] values, int index) {
+        final Object removedValue = values[index];
+        System.arraycopy(values, index+1, values, index, 
values.length-index-1);
+        values[values.length-1] = null; //remove reference
+        return removedValue;
+    }
+
+    /**
+     * Remove element at index.
+     * Move elements after index by -1.
+     * Last element is set to zero
+     *
+     * @param values original array
+     * @param index removed element index
+     * @return removed value
+     */
+    public static int removeWithin(int[] values, int index) {
+        final int removedValue = values[index];
+        System.arraycopy(values, index+1, values, index, 
values.length-index-1);
+        values[values.length-1] = 0;
+        return removedValue;
+    }
 }
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/maths/ReadOnly.java 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/maths/ReadOnly.java
index 33d3a4db8d..9ff8cffef5 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/maths/ReadOnly.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/maths/ReadOnly.java
@@ -347,6 +347,24 @@ public final class ReadOnly {
             }
             return v;
         }
+
+        /**
+         * Create a new tuple with the values of the given axes, in the given 
order.
+         * Axes can be omitted or repeated, for example {@code swizzle(1, 0)} 
swaps the
+         * two first values and {@code swizzle(0, 0, 0)} repeats the first one.
+         * Vector CRS will be lost.
+         *
+         * @param axes indices of the values of this tuple to copy, one per 
dimension of the result
+         * @return Vector of dimension {@code axes.length}
+         * @throws IndexOutOfBoundsException if an axis index is not valid
+         */
+        default org.apache.sis.maths.Vector<?> swizzle(int ... axes) throws 
IndexOutOfBoundsException {
+            final org.apache.sis.maths.Vector<?> v = 
Vectors.create(axes.length, getDataType());
+            for (int i = 0; i < axes.length; i++) {
+                v.set(i, get(axes[i]));
+            }
+            return v;
+        }
     }
 
     public static interface Affine<T extends Affine<T>> extends Transform {
diff --git 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/maths/AbstractVectorTest.java
 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/maths/AbstractVectorTest.java
index e61ef375c6..78bbd04e5e 100644
--- 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/maths/AbstractVectorTest.java
+++ 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/maths/AbstractVectorTest.java
@@ -68,6 +68,7 @@ public abstract class AbstractVectorTest {
         testToArray(tuple);
         testEquality(tuple);
         testCopyDataType(tuple);
+        testSwizzle(tuple);
 
         switch (tuple.getDataType()) {
             case BYTE :
@@ -265,6 +266,42 @@ public abstract class AbstractVectorTest {
         }
     }
 
+    /**
+     * Test the creation of a tuple from some axes of another one.
+     */
+    private void testSwizzle(Vector<?> tuple) {
+        final int dim = tuple.getDimension();
+        for (int i = 0; i < dim; i++) {
+            tuple.set(i, i+1);
+        }
+        //reverse order
+        final int[] reverse = new int[dim];
+        final double[] expected = new double[dim];
+        for (int i = 0; i < dim; i++) {
+            reverse[i] = dim - 1 - i;
+            expected[i] = dim - i;
+        }
+        Vector<?> swizzled = tuple.swizzle(reverse);
+        assertEquals(tuple.getDataType(), swizzled.getDataType());
+        assertArrayEquals(expected, swizzled.toArrayDouble(), TOLERANCE);
+
+        //repeated and omitted axes
+        swizzled = tuple.swizzle(dim - 1, 0, dim - 1);
+        assertArrayEquals(new double[] {dim, 1, dim}, 
swizzled.toArrayDouble(), TOLERANCE);
+
+        //the result is independent of the original tuple
+        swizzled.set(1, 100);
+        assertEquals(1, tuple.get(0), TOLERANCE);
+
+        //test out of range
+        try {
+            tuple.swizzle(dim);
+            fail(UNVALID_INDEX_EXPECTED);
+        } catch (IndexOutOfBoundsException ex) {
+            //ok
+        }
+    }
+
     private void testExtremum(Vector<?> tuple, double value) {
 
         for (int i=0;i<tuple.getDimension();i++) {

Reply via email to