diff --git a/Comparison/src/main/java/cz/fidentis/analyst/visitors/kdtree/ClosestNodeAbstractVisitor.java b/Comparison/src/main/java/cz/fidentis/analyst/visitors/kdtree/ClosestNodeAbstractVisitor.java deleted file mode 100644 index 1cdaa28a47ac80ae31b72c7f1e263ed5b03249ba..0000000000000000000000000000000000000000 --- a/Comparison/src/main/java/cz/fidentis/analyst/visitors/kdtree/ClosestNodeAbstractVisitor.java +++ /dev/null @@ -1,102 +0,0 @@ -package cz.fidentis.analyst.visitors.kdtree; - -import cz.fidentis.analyst.kdtree.KdNode; -import cz.fidentis.analyst.kdtree.KdTreeVisitor; -import cz.fidentis.analyst.mesh.core.MeshPoint; -import java.util.LinkedList; -import java.util.Queue; -import javax.vecmath.Vector3d; - -/** - * Abstract super-class for visitors that find nodes of k-d trees that are closest to the given 3D location. - * <p> - * A single visitor can be applied to multiple k-d trees. - * <ul> - * <li>If one tree has a closer distance to the given 3D point than all other trees, - * then only this tree is taken into consideration. If there are multiple trees - * with the same minimal distance, then only one is taken into account.</li> - * <li>From the one closets tree, only one closest node is returned. - * If there are multiple nodes with the same minimal distance then only (random) - * one is selected and returned.</li> - * </ul> - * </p> - * <p> - * This visitor is thread-safe. - * </p> - * - * @author Daniel Schramm - */ -public abstract class ClosestNodeAbstractVisitor extends KdTreeVisitor { - - private final Vector3d myPoint; - private double distance = Double.POSITIVE_INFINITY; - - /** - * @param point The 3D location for which the nodes are to be computed. - * @param asynchronous If {@code true}, then asynchronous visitor is created. - * @throws IllegalArgumentException if some parametr is wrong - */ - public ClosestNodeAbstractVisitor(Vector3d point, boolean asynchronous) { - super(asynchronous); - if (point == null) { - throw new IllegalArgumentException("point"); - } - this.myPoint = point; - } - - /** - * Returns the minimal distance - * @return the minimal distance - */ - public double getDistance() { - return distance; - } - - /** - * Returns the 3D point from which the distance is computed - * @return the 3D point from which the distance is computed - */ - protected Vector3d getPoint3d() { - return myPoint; - } - - protected boolean firstIsLessThanSecond(Vector3d v1, Vector3d v2, int level){ - switch (level % 3) { - case 0: - return v1.x <= v2.x; - case 1: - return v1.y <= v2.y; - case 2: - return v1.z <= v2.z; - default: - break; - } - return false; - } - - /** - * Calculates distance between two points - * (currently searched node and point to which we want to find nearest neighbor) - * (based on axis) - * - */ - protected double minDistanceIntersection(Vector3d nodePosition, Vector3d pointPosition, int level){ - switch (level % 3) { - case 0: - return Math.abs(nodePosition.x - pointPosition.x); - case 1: - return Math.abs(nodePosition.y - pointPosition.y); - default: - return Math.abs(nodePosition.z - pointPosition.z); - } - } - - protected boolean updateMinimalDistance(double dist) { - if (dist< distance) { - distance = dist; - return true; - } else { - return false; - } - } -} diff --git a/Comparison/src/main/java/cz/fidentis/analyst/visitors/kdtree/ClosestNodeMultipleVisitor.java b/Comparison/src/main/java/cz/fidentis/analyst/visitors/kdtree/ClosestNodeMultipleVisitor.java index 221637b17e995b2b81ea03adb77ec5290c4c30b0..af9a3c123da9752f8cb4b271f4b100829a9d2e42 100644 --- a/Comparison/src/main/java/cz/fidentis/analyst/visitors/kdtree/ClosestNodeMultipleVisitor.java +++ b/Comparison/src/main/java/cz/fidentis/analyst/visitors/kdtree/ClosestNodeMultipleVisitor.java @@ -2,6 +2,7 @@ package cz.fidentis.analyst.visitors.kdtree; import cz.fidentis.analyst.kdtree.KdNode; import cz.fidentis.analyst.kdtree.KdTree; +import cz.fidentis.analyst.kdtree.KdTreeVisitor; import cz.fidentis.analyst.mesh.core.MeshPoint; import java.util.Collections; import java.util.HashSet; @@ -30,8 +31,10 @@ import javax.vecmath.Vector3d; * * @author Daniel Schramm */ -public class ClosestNodeMultipleVisitor extends ClosestNodeAbstractVisitor { +public class ClosestNodeMultipleVisitor extends KdTreeVisitor { + private final Vector3d myPoint; + private double distance = Double.POSITIVE_INFINITY; private final Set<KdNode> closest = new HashSet<>(); /** @@ -40,7 +43,11 @@ public class ClosestNodeMultipleVisitor extends ClosestNodeAbstractVisitor { * @throws IllegalArgumentException if some parametr is wrong */ public ClosestNodeMultipleVisitor(Vector3d point, boolean asynchronous) { - super(point, asynchronous); + super(asynchronous); + if (point == null) { + throw new IllegalArgumentException("point"); + } + this.myPoint = point; } /** @@ -51,6 +58,14 @@ public class ClosestNodeMultipleVisitor extends ClosestNodeAbstractVisitor { public Set<KdNode> getClosestNodes() { return Collections.unmodifiableSet(closest); } + + /** + * Returns the minimal distance + * @return the minimal distance + */ + public double getDistance() { + return distance; + } @Override protected void visitKdTree(KdTree kdTree) { @@ -67,14 +82,14 @@ public class ClosestNodeMultipleVisitor extends ClosestNodeAbstractVisitor { */ while (searchedNode != null) { final Vector3d nodePos = searchedNode.getLocation(); - final double dist = MeshPoint.distance(getPoint3d(), nodePos); + final double dist = MeshPoint.distance(myPoint, nodePos); synchronized (this) { if (updateMinimalDistance(dist) && !closest.isEmpty()) { closest.clear(); } } - if (firstIsLessThanSecond(getPoint3d(), nodePos, searchedNode.getDepth())) { + if (firstIsLessThanSecond(myPoint, nodePos, searchedNode.getDepth())) { searchedNode = searchedNode.getLesser(); } else { searchedNode = searchedNode.getGreater(); @@ -92,20 +107,20 @@ public class ClosestNodeMultipleVisitor extends ClosestNodeAbstractVisitor { searchedNode = queue.poll(); final Vector3d nodePos = searchedNode.getLocation(); - final double dist = MeshPoint.distance(getPoint3d(), nodePos); + final double dist = MeshPoint.distance(myPoint, nodePos); synchronized (this) { if (updateMinimalDistance(dist)) { closest.clear(); closest.add(searchedNode); - } else if (dist == getDistance()) { + } else if (dist == distance) { closest.add(searchedNode); } } - final double distOnAxis = minDistanceIntersection(nodePos, getPoint3d(), searchedNode.getDepth()); + final double distOnAxis = minDistanceIntersection(nodePos, myPoint, searchedNode.getDepth()); - if (distOnAxis > getDistance()) { - if (firstIsLessThanSecond(getPoint3d(), nodePos, searchedNode.getDepth())) { + if (distOnAxis > distance) { + if (firstIsLessThanSecond(myPoint, nodePos, searchedNode.getDepth())) { if (searchedNode.getLesser() != null) { queue.add(searchedNode.getLesser()); } @@ -125,4 +140,43 @@ public class ClosestNodeMultipleVisitor extends ClosestNodeAbstractVisitor { } } + protected boolean firstIsLessThanSecond(Vector3d v1, Vector3d v2, int level){ + switch (level % 3) { + case 0: + return v1.x <= v2.x; + case 1: + return v1.y <= v2.y; + case 2: + return v1.z <= v2.z; + default: + break; + } + return false; + } + + /** + * Calculates distance between two points + * (currently searched node and point to which we want to find nearest neighbor) + * (based on axis) + * + */ + protected double minDistanceIntersection(Vector3d nodePosition, Vector3d pointPosition, int level){ + switch (level % 3) { + case 0: + return Math.abs(nodePosition.x - pointPosition.x); + case 1: + return Math.abs(nodePosition.y - pointPosition.y); + default: + return Math.abs(nodePosition.z - pointPosition.z); + } + } + + protected boolean updateMinimalDistance(double dist) { + if (dist< distance) { + distance = dist; + return true; + } else { + return false; + } + } } diff --git a/Comparison/src/main/java/cz/fidentis/analyst/visitors/kdtree/ClosestNodeVisitor.java b/Comparison/src/main/java/cz/fidentis/analyst/visitors/kdtree/ClosestNodeVisitor.java index fb063f5271513250ee40ee067f293aec5b707ea5..b9828ed46cc66abc9591336927ab72eca4fcb225 100644 --- a/Comparison/src/main/java/cz/fidentis/analyst/visitors/kdtree/ClosestNodeVisitor.java +++ b/Comparison/src/main/java/cz/fidentis/analyst/visitors/kdtree/ClosestNodeVisitor.java @@ -2,6 +2,7 @@ package cz.fidentis.analyst.visitors.kdtree; import cz.fidentis.analyst.kdtree.KdNode; import cz.fidentis.analyst.kdtree.KdTree; +import cz.fidentis.analyst.kdtree.KdTreeVisitor; import cz.fidentis.analyst.mesh.core.MeshPoint; import java.util.LinkedList; import java.util.Queue; @@ -26,8 +27,10 @@ import javax.vecmath.Vector3d; * * @author Daniel Schramm */ -public class ClosestNodeVisitor extends ClosestNodeAbstractVisitor { +public class ClosestNodeVisitor extends KdTreeVisitor { + private final Vector3d myPoint; + private double distance = Double.POSITIVE_INFINITY; private KdNode closestNode; /** @@ -36,7 +39,11 @@ public class ClosestNodeVisitor extends ClosestNodeAbstractVisitor { * @throws IllegalArgumentException if some parametr is wrong */ public ClosestNodeVisitor(Vector3d point, boolean asynchronous) { - super(point, asynchronous); + super(asynchronous); + if (point == null) { + throw new IllegalArgumentException("point"); + } + this.myPoint = point; } /** @@ -48,6 +55,14 @@ public class ClosestNodeVisitor extends ClosestNodeAbstractVisitor { return closestNode; } + /** + * Returns the minimal distance + * @return the minimal distance + */ + public double getDistance() { + return distance; + } + @Override protected void visitKdTree(KdTree kdTree) { final KdNode root = kdTree.getRoot(); @@ -64,13 +79,13 @@ public class ClosestNodeVisitor extends ClosestNodeAbstractVisitor { while (searchedNode != null) { Vector3d nodePos = searchedNode.getLocation(); - double dist = MeshPoint.distance(getPoint3d(), nodePos); + double dist = MeshPoint.distance(myPoint, nodePos); if (dist < minDistance) { nearNode = searchedNode; minDistance = dist; } - if (firstIsLessThanSecond(getPoint3d(), nodePos, searchedNode.getDepth())) { + if (firstIsLessThanSecond(myPoint, nodePos, searchedNode.getDepth())) { searchedNode = searchedNode.getLesser(); } else { searchedNode = searchedNode.getGreater(); @@ -94,16 +109,16 @@ public class ClosestNodeVisitor extends ClosestNodeAbstractVisitor { searchedNode = queue.poll(); Vector3d nodePos = searchedNode.getLocation(); - double dist = MeshPoint.distance(getPoint3d(), nodePos); + double dist = MeshPoint.distance(myPoint, nodePos); if (dist < minDistance) { nearNode = searchedNode; minDistance = dist; } - distOnAxis = minDistanceIntersection(nodePos, getPoint3d(), searchedNode.getDepth()); + distOnAxis = minDistanceIntersection(nodePos, myPoint, searchedNode.getDepth()); if (distOnAxis > minDistance) { - if (firstIsLessThanSecond(getPoint3d(), nodePos, searchedNode.getDepth())) { + if (firstIsLessThanSecond(myPoint, nodePos, searchedNode.getDepth())) { if (searchedNode.getLesser() != null) { queue.add(searchedNode.getLesser()); } @@ -122,11 +137,51 @@ public class ClosestNodeVisitor extends ClosestNodeAbstractVisitor { } } - final double foundDistance = MeshPoint.distance(getPoint3d(), nearNode.getLocation()); + final double foundDistance = MeshPoint.distance(myPoint, nearNode.getLocation()); synchronized (this) { if (updateMinimalDistance(foundDistance)) { closestNode = nearNode; } } } + protected boolean firstIsLessThanSecond(Vector3d v1, Vector3d v2, int level){ + switch (level % 3) { + case 0: + return v1.x <= v2.x; + case 1: + return v1.y <= v2.y; + case 2: + return v1.z <= v2.z; + default: + break; + } + return false; + } + + /** + * Calculates distance between two points + * (currently searched node and point to which we want to find nearest neighbor) + * (based on axis) + * + */ + protected double minDistanceIntersection(Vector3d nodePosition, Vector3d pointPosition, int level){ + switch (level % 3) { + case 0: + return Math.abs(nodePosition.x - pointPosition.x); + case 1: + return Math.abs(nodePosition.y - pointPosition.y); + default: + return Math.abs(nodePosition.z - pointPosition.z); + } + } + + protected boolean updateMinimalDistance(double dist) { + if (dist< distance) { + distance = dist; + return true; + } else { + return false; + } + } + }