From f42912667f4d3a9c76844742c7fab223efb44e04 Mon Sep 17 00:00:00 2001 From: Maria Kocurekova <xkocure1@fi.muni.cz> Date: Thu, 21 Jan 2021 10:09:59 +0100 Subject: [PATCH] #35 - add visitor --- .../fidentis/analyst/mesh/KdTree/KdNode.java | 10 +- .../analyst/mesh/KdTree/KdTreeImpl.java | 38 ++++-- .../mesh/visitors/KdTreeBuildVisitor.java | 19 +++ .../analyst/mesh/KdTree/kdTreeTest.java | 118 +++++++++++++++++- 4 files changed, 169 insertions(+), 16 deletions(-) create mode 100644 MeshModel/src/main/java/cz/fidentis/analyst/mesh/visitors/KdTreeBuildVisitor.java diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/KdTree/KdNode.java b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/KdTree/KdNode.java index 77dfc3ac..842e024d 100644 --- a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/KdTree/KdNode.java +++ b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/KdTree/KdNode.java @@ -3,6 +3,7 @@ package cz.fidentis.analyst.mesh.KdTree; import cz.fidentis.analyst.mesh.core.MeshFacet; import cz.fidentis.analyst.mesh.core.MeshPoint; +import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -28,10 +29,13 @@ public class KdNode { } //return only one index (index of MeshPoint in the first MeshFacet) - public int getIndex() { + /* public int getIndex() { Map.Entry<MeshFacet, Integer> entry = facets.entrySet().iterator().next(); return entry.getValue(); - } + }*/ + public Map<MeshFacet, Integer> getIndex(){ + return Collections.unmodifiableMap(facets); + } public int getDepth() { return depth; @@ -66,7 +70,7 @@ public class KdNode { } public Map<MeshFacet, Integer> getFacets() { - return facets; + return Collections.unmodifiableMap(facets); } public KdNode setParent(KdNode parent) { diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/KdTree/KdTreeImpl.java b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/KdTree/KdTreeImpl.java index 52c5c890..c49d4a91 100644 --- a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/KdTree/KdTreeImpl.java +++ b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/KdTree/KdTreeImpl.java @@ -1,6 +1,7 @@ package cz.fidentis.analyst.mesh.KdTree; import cz.fidentis.analyst.mesh.core.MeshFacet; +import cz.fidentis.analyst.mesh.core.MeshFacetImpl; import cz.fidentis.analyst.mesh.core.MeshPoint; import java.util.*; @@ -78,22 +79,43 @@ public class KdTreeImpl { private final Comparator<Integer> zIndexComparatorF = Comparator.comparingDouble(i -> Objects.requireNonNull(findPointFacetIndex(i)).getPoint().getPosition().z); - public KdTreeImpl(List<MeshFacet> facets) { + + + KdTreeImpl(Set<MeshPoint> points) { + if(points == null) { + this.root = null; + this.facets = null; + return; + } + MeshFacet newFacet = new MeshFacetImpl(); + for(MeshPoint point : points) { + newFacet.addVertex(point); + } + this.facets = new LinkedList<>(Collections.singleton(newFacet)); + prepareForBuildTree(); + + } + + public KdTreeImpl(MeshFacet facet) { + this(new LinkedList<>(Collections.singleton(facet))); + } + + KdTreeImpl(List<MeshFacet> facets) { if(facets == null || facets.isEmpty() || facets.get(0).getVertices().isEmpty() ){ this.root = null; this.facets = null; return; } + this.facets = facets; + prepareForBuildTree(); + } + private void prepareForBuildTree() { int countOfVertices = 0; for (MeshFacet facet : facets) { countOfVertices += facet.getVertices().size(); } - - - this.facets = facets; - List<Integer> sortedByX = sortPointsF( X_AXIS); List<Integer> sortedByY = sortPointsF( Y_AXIS); List<Integer> sortedByZ = sortPointsF( Z_AXIS); @@ -125,6 +147,9 @@ public class KdTreeImpl { } } + + + private Triple findPointFacetIndex(int index) { Triple result; int countOfCheckedVertices = 0; @@ -164,7 +189,6 @@ public class KdTreeImpl { } - private List<Integer> sortPointsF(int level){ int countOfVertices = 0; for (MeshFacet facet : facets) { @@ -415,7 +439,7 @@ public class KdTreeImpl { * @param p MeshPoint * @return index of MeshPoint in MeshFacetImpl -> vertices */ - public Integer nearestNeighbourIndex(MeshPoint p){ + public Map<MeshFacet, Integer> nearestNeighbourIndex(MeshPoint p){ KdNode nn = nearestNeighbourNode(p); if(nn == null){ diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/visitors/KdTreeBuildVisitor.java b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/visitors/KdTreeBuildVisitor.java new file mode 100644 index 00000000..ac0212ba --- /dev/null +++ b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/visitors/KdTreeBuildVisitor.java @@ -0,0 +1,19 @@ +package cz.fidentis.analyst.mesh.visitors; + +import cz.fidentis.analyst.mesh.KdTree.KdTreeImpl; + +import cz.fidentis.analyst.mesh.core.MeshFacet; + + +public class KdTreeBuildVisitor implements Visitor { + private KdTreeImpl kdTree; + + @Override + public void visitMeshFacet(MeshFacet facet) { + kdTree = new KdTreeImpl(facet); + } + + public KdTreeImpl getKdTree() { + return kdTree; + } +} diff --git a/MeshModel/src/test/java/cz/fidentis/analyst/mesh/KdTree/kdTreeTest.java b/MeshModel/src/test/java/cz/fidentis/analyst/mesh/KdTree/kdTreeTest.java index eeec7de1..9a1d2766 100644 --- a/MeshModel/src/test/java/cz/fidentis/analyst/mesh/KdTree/kdTreeTest.java +++ b/MeshModel/src/test/java/cz/fidentis/analyst/mesh/KdTree/kdTreeTest.java @@ -6,9 +6,7 @@ import cz.fidentis.analyst.mesh.core.MeshPointImpl; import org.junit.jupiter.api.Test; import javax.vecmath.Vector3d; -import java.util.LinkedList; -import java.util.List; -import java.util.Random; +import java.util.*; import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -234,10 +232,118 @@ public class kdTreeTest { Random r = new Random(); MeshPoint p = points.get(r.nextInt(points.size())); - int found = tree.nearestNeighbourIndex(p); - assertEquals(points.get(found), p); - assertEquals(0.0f, distancePoints(points.get(found), p)); + MeshPoint foundP = tree.nearestNeighbour(p); + Map<MeshFacet, Integer> found = tree.nearestNeighbourIndex(p); + Map.Entry<MeshFacet, Integer> entry = found.entrySet().iterator().next(); + + assertEquals(foundP, p); + assertEquals(entry.getKey().getVertex(entry.getValue()),p ); + + + } + + @Test + public void testIndexFoundTwoFacetsAllDuplicates(){ + List<MeshFacet> facets = new LinkedList<>(); + + MeshFacet facet1 = new MeshFacetImpl(); + MeshFacet facet2 = new MeshFacetImpl(); + + + List<MeshPoint> points = new LinkedList<>(); + Vector3d positionOfPoints; + + for(int i = 0; i < 10; i++){ + positionOfPoints = new Vector3d(0.1f * i, 0.5f * i, 0.7f * i); + points.add(new MeshPointImpl(positionOfPoints, normalAndTextCoord, normalAndTextCoord)); + facet1.addVertex(new MeshPointImpl(positionOfPoints, normalAndTextCoord, normalAndTextCoord)); + } + for(int i =0; i < 10; i++){ + positionOfPoints = new Vector3d(0.1f * i, 0.5f * i, 0.7f * i); + points.add(new MeshPointImpl(positionOfPoints, normalAndTextCoord, normalAndTextCoord)); + facet2.addVertex(new MeshPointImpl(positionOfPoints, normalAndTextCoord, normalAndTextCoord)); + } + + + facets.add(facet1); + facets.add(facet2); + KdTreeImpl tree = new KdTreeImpl(facets); + + Random r = new Random(); + + MeshPoint p = points.get(r.nextInt(points.size())); + + MeshPoint foundP = tree.nearestNeighbour(p); + Map<MeshFacet, Integer> found = tree.nearestNeighbourIndex(p); + Map.Entry<MeshFacet, Integer> entry = found.entrySet().iterator().next(); + + assertEquals(foundP, p); + assertEquals(entry.getKey().getVertex(entry.getValue()),p ); + + MeshFacet second = (new ArrayList<MeshFacet>(found.keySet())).get(1); + int secondIndex = (new ArrayList<Integer>(found.values())).get(1); + assertEquals(second.getVertex(secondIndex),p ); + + assertEquals(0.0f, distancePoints(second.getVertex(secondIndex), entry.getKey().getVertex(entry.getValue()))); + } + + + @Test + public void testOneFacetNearNeighbourIndex(){ + MeshFacet facet1 = new MeshFacetImpl(); + + + List<MeshPoint> points = new LinkedList<>(); + Vector3d positionOfPoints; + + for(int i = 1; i < 20; i++){ + positionOfPoints = new Vector3d(0.1f * i, 0.5f * i, 0.7f * i); + points.add(new MeshPointImpl(positionOfPoints, normalAndTextCoord, normalAndTextCoord)); + facet1.addVertex(new MeshPointImpl(positionOfPoints, normalAndTextCoord, normalAndTextCoord)); + } + + KdTreeImpl tree = new KdTreeImpl(facet1); + + Random r = new Random(); + + MeshPoint p = points.get(r.nextInt(points.size())); + + MeshPoint foundP = tree.nearestNeighbour(p); + Map<MeshFacet, Integer> found = tree.nearestNeighbourIndex(p); + Map.Entry<MeshFacet, Integer> entry = found.entrySet().iterator().next(); + + assertEquals(foundP, p); + assertEquals(entry.getKey().getVertex(entry.getValue()),p ); + + + } + + @Test + public void testSetOfPointsNearNeighbourIndex(){ + Set<MeshPoint> points = new HashSet<>(); + List<MeshPoint> pointsList = new LinkedList<>(); + Vector3d positionOfPoints; + + for(int i = 1; i < 20; i++){ + positionOfPoints = new Vector3d(0.1f * i, 0.5f * i, 0.7f * i); + points.add(new MeshPointImpl(positionOfPoints, normalAndTextCoord, normalAndTextCoord)); + pointsList.add(new MeshPointImpl(positionOfPoints, normalAndTextCoord, normalAndTextCoord)); + } + + KdTreeImpl tree = new KdTreeImpl(points); + + Random r = new Random(); + MeshPoint p = pointsList.get(r.nextInt(points.size())); + + MeshPoint foundP = tree.nearestNeighbour(p); + Map<MeshFacet, Integer> found = tree.nearestNeighbourIndex(p); + Map.Entry<MeshFacet, Integer> entry = found.entrySet().iterator().next(); + + assertEquals(foundP, p); + assertEquals(entry.getKey().getVertex(entry.getValue()),p ); + + } /* -- GitLab