Skip to content

Commit f9cd535

Browse files
author
rimadoma
committed
Add tuple3d centroid op
1 parent 010510b commit f9cd535

File tree

4 files changed

+104
-0
lines changed

4 files changed

+104
-0
lines changed

pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,10 @@
260260
<groupId>org.scijava</groupId>
261261
<artifactId>scripting-javascript</artifactId>
262262
</dependency>
263+
<dependency>
264+
<groupId>org.scijava</groupId>
265+
<artifactId>vecmath</artifactId>
266+
</dependency>
263267

264268
<!-- Third party dependencies -->
265269
<dependency>
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package net.imagej.ops.geom;
2+
3+
import net.imagej.ops.Ops;
4+
import net.imagej.ops.special.function.AbstractUnaryFunctionOp;
5+
import org.scijava.plugin.Plugin;
6+
import org.scijava.vecmath.Tuple3d;
7+
import org.scijava.vecmath.Vector3d;
8+
9+
import java.util.Collection;
10+
11+
/**
12+
* Calculates the centroid (geometrical centre) of the given tuples
13+
*
14+
* @author Richard Domander (Royal Veterinary College, London)
15+
*/
16+
@Plugin(type = Ops.Geometric.Centroid.class)
17+
public class CentroidTuple3D extends AbstractUnaryFunctionOp<Collection<? extends Tuple3d>, Vector3d>
18+
implements Ops.Geometric.Centroid {
19+
@Override
20+
public Vector3d compute1(final Collection<? extends Tuple3d> input) {
21+
final int vectors = input.size();
22+
if (vectors == 0) {
23+
return new Vector3d(Double.NaN, Double.NaN, Double.NaN);
24+
}
25+
26+
final Vector3d sum = new Vector3d(0.0, 0.0, 0.0);
27+
input.stream().forEach(sum::add);
28+
sum.scale(1.0 / vectors);
29+
30+
return sum;
31+
}
32+
}

src/main/java/net/imagej/ops/geom/GeomNamespace.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@
5151

5252
import org.apache.commons.math3.linear.RealMatrix;
5353
import org.scijava.plugin.Plugin;
54+
import org.scijava.vecmath.Tuple3d;
55+
import org.scijava.vecmath.Vector3d;
56+
57+
import java.util.Collection;
5458

5559
/**
5660
* Namespace for Geom.
@@ -228,6 +232,11 @@ public RealLocalizable centroid(final Mesh in) {
228232
return result;
229233
}
230234

235+
@OpMethod(op = net.imagej.ops.geom.CentroidTuple3D.class)
236+
public Vector3d centroid(final Collection<? extends Tuple3d> in) {
237+
return (Vector3d) ops().run(net.imagej.ops.Ops.Geometric.Centroid.class, in);
238+
}
239+
231240
@OpMethod(op = net.imagej.ops.geom.geom2d.DefaultCircularity.class)
232241
public DoubleType circularity(final Polygon2D in) {
233242
final DoubleType result =
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package net.imagej.ops.geom;
2+
3+
import net.imagej.ops.AbstractOpTest;
4+
import org.junit.Test;
5+
import org.scijava.vecmath.Vector3d;
6+
7+
import java.util.Arrays;
8+
import java.util.Collections;
9+
import java.util.List;
10+
import java.util.stream.DoubleStream;
11+
12+
import static org.junit.Assert.assertEquals;
13+
import static org.junit.Assert.assertTrue;
14+
15+
/**
16+
* Unit tests for {@link CentroidTuple3D}
17+
*
18+
* @author Richard Domander (Royal Veterinary College, London)
19+
*/
20+
public class CentroidTuple3DTest extends AbstractOpTest {
21+
@Test
22+
public void testCompute1EmptyCollection() throws Exception {
23+
final List<Vector3d> emptyList = Collections.emptyList();
24+
25+
final Vector3d result = (Vector3d) ops.run(CentroidTuple3D.class, emptyList);
26+
27+
assertTrue("Coordinates should all be NaN",
28+
DoubleStream.of(result.x, result.y, result.z).allMatch(Double::isNaN));
29+
}
30+
31+
@Test
32+
public void testCompute1SingleVector() throws Exception {
33+
final Vector3d vector = new Vector3d(1.0, 2.0, 3.0);
34+
final List<Vector3d> vectors = Collections.singletonList(vector);
35+
36+
final Vector3d result = (Vector3d) ops.run(CentroidTuple3D.class, vectors);
37+
38+
assertEquals("Incorrect centroid vector", vector, result);
39+
}
40+
41+
@Test
42+
public void testCompute1() throws Exception {
43+
final Vector3d expected = new Vector3d(0.5, 0.5, 0.5);
44+
final List<Vector3d> cubeVectors = Arrays.asList(
45+
new Vector3d(0.0, 0.0, 0.0),
46+
new Vector3d(1.0, 0.0, 0.0),
47+
new Vector3d(1.0, 1.0, 0.0),
48+
new Vector3d(0.0, 1.0, 0.0),
49+
new Vector3d(0.0, 0.0, 1.0),
50+
new Vector3d(1.0, 0.0, 1.0),
51+
new Vector3d(1.0, 1.0, 1.0),
52+
new Vector3d(0.0, 1.0, 1.0)
53+
);
54+
55+
final Vector3d result = (Vector3d) ops.run(CentroidTuple3D.class, cubeVectors);
56+
57+
assertEquals("Incorrect centroid vector", expected, result);
58+
}
59+
}

0 commit comments

Comments
 (0)