diff --git a/hipparchus-geometry/src/changes/changes.xml b/hipparchus-geometry/src/changes/changes.xml index cbefc1ef0..ce6b0c6a1 100644 --- a/hipparchus-geometry/src/changes/changes.xml +++ b/hipparchus-geometry/src/changes/changes.xml @@ -49,6 +49,12 @@ If the output is not quite correct, check for invisible trailing spaces! Hipparchus Geometry Release Notes + + Added point type to geometry classes parameters + + + Improved robustness of BSP tree operations + Migrated tests from JUnit 4 to JUnit 5 diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/oned/IntervalsSet.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/oned/IntervalsSet.java index 944b8f9aa..83f53fba5 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/oned/IntervalsSet.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/oned/IntervalsSet.java @@ -27,7 +27,6 @@ import java.util.List; import java.util.NoSuchElementException; -import org.hipparchus.geometry.Point; import org.hipparchus.geometry.partitioning.AbstractRegion; import org.hipparchus.geometry.partitioning.BSPTree; import org.hipparchus.geometry.partitioning.BoundaryProjection; @@ -36,7 +35,8 @@ /** This class represents a 1D region: a set of intervals. */ -public class IntervalsSet extends AbstractRegion implements Iterable { +public class IntervalsSet extends AbstractRegion + implements Iterable { /** Build an intervals set representing the whole real line. * @param tolerance tolerance below which points are considered identical. @@ -66,7 +66,7 @@ public IntervalsSet(final double lower, final double upper, final double toleran * @param tree inside/outside BSP tree representing the intervals set * @param tolerance tolerance below which points are considered identical. */ - public IntervalsSet(final BSPTree tree, final double tolerance) { + public IntervalsSet(final BSPTree tree, final double tolerance) { super(tree, tolerance); } @@ -90,7 +90,7 @@ public IntervalsSet(final BSPTree tree, final double tolerance) { * @param boundary collection of boundary elements * @param tolerance tolerance below which points are considered identical. */ - public IntervalsSet(final Collection> boundary, + public IntervalsSet(final Collection> boundary, final double tolerance) { super(boundary, tolerance); } @@ -103,47 +103,38 @@ public IntervalsSet(final Collection> boundary, * @param tolerance tolerance below which points are considered identical. * @return the built tree */ - private static BSPTree buildTree(final double lower, final double upper, - final double tolerance) { + private static BSPTree buildTree(final double lower, final double upper, + final double tolerance) { if (Double.isInfinite(lower) && (lower < 0)) { if (Double.isInfinite(upper) && (upper > 0)) { // the tree must cover the whole real line - return new BSPTree(Boolean.TRUE); + return new BSPTree<>(Boolean.TRUE); } // the tree must be open on the negative infinity side - final SubHyperplane upperCut = + final SubHyperplane upperCut = new OrientedPoint(new Vector1D(upper), true, tolerance).wholeHyperplane(); - return new BSPTree(upperCut, - new BSPTree(Boolean.FALSE), - new BSPTree(Boolean.TRUE), - null); + return new BSPTree<>(upperCut, new BSPTree<>(Boolean.FALSE), new BSPTree<>(Boolean.TRUE), null); } - final SubHyperplane lowerCut = + final SubHyperplane lowerCut = new OrientedPoint(new Vector1D(lower), false, tolerance).wholeHyperplane(); if (Double.isInfinite(upper) && (upper > 0)) { // the tree must be open on the positive infinity side - return new BSPTree(lowerCut, - new BSPTree(Boolean.FALSE), - new BSPTree(Boolean.TRUE), - null); + return new BSPTree<>(lowerCut, new BSPTree<>(Boolean.FALSE), new BSPTree<>(Boolean.TRUE), null); } // the tree must be bounded on the two sides - final SubHyperplane upperCut = + final SubHyperplane upperCut = new OrientedPoint(new Vector1D(upper), true, tolerance).wholeHyperplane(); - return new BSPTree(lowerCut, - new BSPTree(Boolean.FALSE), - new BSPTree(upperCut, - new BSPTree(Boolean.FALSE), - new BSPTree(Boolean.TRUE), - null), - null); + return new BSPTree<>(lowerCut, + new BSPTree<>(Boolean.FALSE), + new BSPTree<>(upperCut, new BSPTree<>(Boolean.FALSE), new BSPTree<>(Boolean.TRUE), null), + null); } /** {@inheritDoc} */ @Override - public IntervalsSet buildNew(final BSPTree tree) { + public IntervalsSet buildNew(final BSPTree tree) { return new IntervalsSet(tree, getTolerance()); } @@ -151,7 +142,7 @@ public IntervalsSet buildNew(final BSPTree tree) { @Override protected void computeGeometricalProperties() { if (getTree(false).getCut() == null) { - setBarycenter((Point) Vector1D.NaN); + setBarycenter(Vector1D.NaN); setSize(((Boolean) getTree(false).getAttribute()) ? Double.POSITIVE_INFINITY : 0); } else { double size = 0.0; @@ -162,11 +153,11 @@ protected void computeGeometricalProperties() { } setSize(size); if (Double.isInfinite(size)) { - setBarycenter((Point) Vector1D.NaN); + setBarycenter(Vector1D.NaN); } else if (size >= Precision.SAFE_MIN) { - setBarycenter((Point) new Vector1D(sum / size)); + setBarycenter(new Vector1D(sum / size)); } else { - setBarycenter((Point) ((OrientedPoint) getTree(false).getCut().getHyperplane()).getLocation()); + setBarycenter(((OrientedPoint) getTree(false).getCut().getHyperplane()).getLocation()); } } } @@ -178,7 +169,7 @@ protected void computeGeometricalProperties() { * instance is empty) */ public double getInf() { - BSPTree node = getTree(false); + BSPTree node = getTree(false); double inf = Double.POSITIVE_INFINITY; while (node.getCut() != null) { final OrientedPoint op = (OrientedPoint) node.getCut().getHyperplane(); @@ -195,7 +186,7 @@ public double getInf() { * instance is empty) */ public double getSup() { - BSPTree node = getTree(false); + BSPTree node = getTree(false); double sup = Double.NEGATIVE_INFINITY; while (node.getCut() != null) { final OrientedPoint op = (OrientedPoint) node.getCut().getHyperplane(); @@ -208,10 +199,10 @@ public double getSup() { /** {@inheritDoc} */ @Override - public BoundaryProjection projectToBoundary(final Point point) { + public BoundaryProjection projectToBoundary(final Vector1D point) { // get position of test point - final double x = ((Vector1D) point).getX(); + final double x = point.getX(); double previous = Double.NEGATIVE_INFINITY; for (final double[] a : this) { @@ -221,9 +212,9 @@ public BoundaryProjection projectToBoundary(final Point(point, finiteOrNullPoint(previous), previousOffset); + return new BoundaryProjection<>(point, finiteOrNullPoint(previous), previousOffset); } else { - return new BoundaryProjection(point, finiteOrNullPoint(a[0]), currentOffset); + return new BoundaryProjection<>(point, finiteOrNullPoint(a[0]), currentOffset); } } else if (x <= a[1]) { // the test point lies within the current interval @@ -231,16 +222,16 @@ public BoundaryProjection projectToBoundary(final Point(point, finiteOrNullPoint(a[1]), offset1); + return new BoundaryProjection<>(point, finiteOrNullPoint(a[1]), offset1); } else { - return new BoundaryProjection(point, finiteOrNullPoint(a[0]), offset0); + return new BoundaryProjection<>(point, finiteOrNullPoint(a[0]), offset0); } } previous = a[1]; } // the test point if past the last sub-interval - return new BoundaryProjection(point, finiteOrNullPoint(previous), x - previous); + return new BoundaryProjection<>(point, finiteOrNullPoint(previous), x - previous); } @@ -277,15 +268,15 @@ public List asList() { * @param root tree root * @return first leaf node */ - private BSPTree getFirstLeaf(final BSPTree root) { + private BSPTree getFirstLeaf(final BSPTree root) { if (root.getCut() == null) { return root; } // find the smallest internal node - BSPTree smallest = null; - for (BSPTree n = root; n != null; n = previousInternalNode(n)) { + BSPTree smallest = null; + for (BSPTree n = root; n != null; n = previousInternalNode(n)) { smallest = n; } @@ -297,10 +288,10 @@ private BSPTree getFirstLeaf(final BSPTree root) { * @return smallest internal node, * or null if there are no internal nodes (i.e. the set is either empty or covers the real line) */ - private BSPTree getFirstIntervalBoundary() { + private BSPTree getFirstIntervalBoundary() { // start search at the tree root - BSPTree node = getTree(false); + BSPTree node = getTree(false); if (node.getCut() == null) { return null; } @@ -321,7 +312,7 @@ private BSPTree getFirstIntervalBoundary() { * @param node internal node to check * @return true if the node corresponds to the start abscissa of an interval */ - private boolean isIntervalStart(final BSPTree node) { + private boolean isIntervalStart(final BSPTree node) { if ((Boolean) leafBefore(node).getAttribute()) { // it has an inside cell before it, it may end an interval but not start it @@ -343,7 +334,7 @@ private boolean isIntervalStart(final BSPTree node) { * @param node internal node to check * @return true if the node corresponds to the end abscissa of an interval */ - private boolean isIntervalEnd(final BSPTree node) { + private boolean isIntervalEnd(final BSPTree node) { if (!(Boolean) leafBefore(node).getAttribute()) { // it has an outside cell before it, it may start an interval but not end it @@ -366,7 +357,7 @@ private boolean isIntervalEnd(final BSPTree node) { * @return next internal node in ascending order, or null * if this is the last internal node */ - private BSPTree nextInternalNode(BSPTree node) { + private BSPTree nextInternalNode(BSPTree node) { if (childAfter(node).getCut() != null) { // the next node is in the sub-tree @@ -386,7 +377,7 @@ private BSPTree nextInternalNode(BSPTree node) { * @return previous internal node in ascending order, or null * if this is the first internal node */ - private BSPTree previousInternalNode(BSPTree node) { + private BSPTree previousInternalNode(BSPTree node) { if (childBefore(node).getCut() != null) { // the next node is in the sub-tree @@ -405,7 +396,7 @@ private BSPTree previousInternalNode(BSPTree node) { * @param node internal node at which the sub-tree starts * @return leaf node just before the internal node */ - private BSPTree leafBefore(BSPTree node) { + private BSPTree leafBefore(BSPTree node) { node = childBefore(node); while (node.getCut() != null) { @@ -420,7 +411,7 @@ private BSPTree leafBefore(BSPTree node) { * @param node internal node at which the sub-tree starts * @return leaf node just after the internal node */ - private BSPTree leafAfter(BSPTree node) { + private BSPTree leafAfter(BSPTree node) { node = childAfter(node); while (node.getCut() != null) { @@ -435,8 +426,8 @@ private BSPTree leafAfter(BSPTree node) { * @param node child node considered * @return true is the node has a parent end is before it in ascending order */ - private boolean isBeforeParent(final BSPTree node) { - final BSPTree parent = node.getParent(); + private boolean isBeforeParent(final BSPTree node) { + final BSPTree parent = node.getParent(); if (parent == null) { return false; } else { @@ -448,8 +439,8 @@ private boolean isBeforeParent(final BSPTree node) { * @param node child node considered * @return true is the node has a parent end is after it in ascending order */ - private boolean isAfterParent(final BSPTree node) { - final BSPTree parent = node.getParent(); + private boolean isAfterParent(final BSPTree node) { + final BSPTree parent = node.getParent(); if (parent == null) { return false; } else { @@ -461,7 +452,7 @@ private boolean isAfterParent(final BSPTree node) { * @param node internal node at which the sub-tree starts * @return child node just before the internal node */ - private BSPTree childBefore(BSPTree node) { + private BSPTree childBefore(BSPTree node) { if (isDirect(node)) { // smaller abscissas are on minus side, larger abscissas are on plus side return node.getMinus(); @@ -475,7 +466,7 @@ private BSPTree childBefore(BSPTree node) { * @param node internal node at which the sub-tree starts * @return child node just after the internal node */ - private BSPTree childAfter(BSPTree node) { + private BSPTree childAfter(BSPTree node) { if (isDirect(node)) { // smaller abscissas are on minus side, larger abscissas are on plus side return node.getPlus(); @@ -489,7 +480,7 @@ private BSPTree childAfter(BSPTree node) { * @param node internal node to check * @return true if the oriented point is direct */ - private boolean isDirect(final BSPTree node) { + private boolean isDirect(final BSPTree node) { return ((OrientedPoint) node.getCut().getHyperplane()).isDirect(); } @@ -497,7 +488,7 @@ private boolean isDirect(final BSPTree node) { * @param node internal node to check * @return abscissa */ - private double getAngle(final BSPTree node) { + private double getAngle(final BSPTree node) { return ((OrientedPoint) node.getCut().getHyperplane()).getLocation().getX(); } @@ -518,7 +509,7 @@ public Iterator iterator() { private class SubIntervalsIterator implements Iterator { /** Current node. */ - private BSPTree current; + private BSPTree current; /** Sub-interval no yet returned. */ private double[] pending; @@ -555,7 +546,7 @@ Double.NEGATIVE_INFINITY, getAngle(current) private void selectPending() { // look for the start of the interval - BSPTree start = current; + BSPTree start = current; while (start != null && !isIntervalStart(start)) { start = nextInternalNode(start); } @@ -568,7 +559,7 @@ private void selectPending() { } // look for the end of the interval - BSPTree end = start; + BSPTree end = start; while (end != null && !isIntervalEnd(end)) { end = nextInternalNode(end); } diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/oned/OrientedPoint.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/oned/OrientedPoint.java index ccf9beda4..f2a019079 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/oned/OrientedPoint.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/oned/OrientedPoint.java @@ -21,8 +21,6 @@ */ package org.hipparchus.geometry.euclidean.oned; -import org.hipparchus.geometry.Point; -import org.hipparchus.geometry.Vector; import org.hipparchus.geometry.partitioning.Hyperplane; /** This class represents a 1D oriented hyperplane. @@ -30,7 +28,7 @@ * boolean.

*

Instances of this class are guaranteed to be immutable.

*/ -public class OrientedPoint implements Hyperplane { +public class OrientedPoint implements Hyperplane { /** Vector location. */ private final Vector1D location; @@ -63,18 +61,10 @@ public OrientedPoint copySelf() { return this; } - /** Get the offset (oriented distance) of a vector. - * @param vector vector to check - * @return offset of the vector - */ - public double getOffset(Vector vector) { - return getOffset((Point) vector); - } - /** {@inheritDoc} */ @Override - public double getOffset(final Point point) { - final double delta = ((Vector1D) point).getX() - location.getX(); + public double getOffset(final Vector1D point) { + final double delta = point.getX() - location.getX(); return direct ? delta : -delta; } @@ -121,14 +111,14 @@ public IntervalsSet wholeSpace() { /** {@inheritDoc} */ @Override - public boolean sameOrientationAs(final Hyperplane other) { - return !(direct ^ ((OrientedPoint) other).direct); + public boolean sameOrientationAs(final Hyperplane other) { + return direct == ((OrientedPoint) other).direct; } /** {@inheritDoc} */ @Override - public Point project(Point point) { + public Vector1D project(Vector1D point) { return location; } diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/oned/SubOrientedPoint.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/oned/SubOrientedPoint.java index 7bc6c083d..de0a8d853 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/oned/SubOrientedPoint.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/oned/SubOrientedPoint.java @@ -30,14 +30,14 @@ * boolean.

*

Instances of this class are guaranteed to be immutable.

*/ -public class SubOrientedPoint extends AbstractSubHyperplane { +public class SubOrientedPoint extends AbstractSubHyperplane { /** Simple constructor. * @param hyperplane underlying hyperplane * @param remainingRegion remaining region of the hyperplane */ - public SubOrientedPoint(final Hyperplane hyperplane, - final Region remainingRegion) { + public SubOrientedPoint(final Hyperplane hyperplane, + final Region remainingRegion) { super(hyperplane, remainingRegion); } @@ -55,21 +55,22 @@ public boolean isEmpty() { /** {@inheritDoc} */ @Override - protected AbstractSubHyperplane buildNew(final Hyperplane hyperplane, - final Region remainingRegion) { + protected AbstractSubHyperplane + buildNew(final Hyperplane hyperplane, + final Region remainingRegion) { return new SubOrientedPoint(hyperplane, remainingRegion); } /** {@inheritDoc} */ @Override - public SplitSubHyperplane split(final Hyperplane hyperplane) { + public SplitSubHyperplane split(final Hyperplane hyperplane) { final double global = hyperplane.getOffset(((OrientedPoint) getHyperplane()).getLocation()); if (global < -hyperplane.getTolerance()) { - return new SplitSubHyperplane(null, this); + return new SplitSubHyperplane<>(null, this); } else if (global > hyperplane.getTolerance()) { - return new SplitSubHyperplane(this, null); + return new SplitSubHyperplane<>(this, null); } else { - return new SplitSubHyperplane(null, null); + return new SplitSubHyperplane<>(null, null); } } diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/threed/Line.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/threed/Line.java index 4c8d39805..3d7940c05 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/threed/Line.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/threed/Line.java @@ -23,8 +23,6 @@ import org.hipparchus.exception.LocalizedCoreFormats; import org.hipparchus.exception.MathIllegalArgumentException; -import org.hipparchus.geometry.Point; -import org.hipparchus.geometry.Vector; import org.hipparchus.geometry.euclidean.oned.Euclidean1D; import org.hipparchus.geometry.euclidean.oned.IntervalsSet; import org.hipparchus.geometry.euclidean.oned.Vector1D; @@ -44,7 +42,7 @@ * @see #fromDirection(Vector3D, Vector3D, double) * @see #Line(Vector3D, Vector3D, double) */ -public class Line implements Embedding { +public class Line implements Embedding { /** Line direction. */ private Vector3D direction; @@ -181,38 +179,20 @@ public Vector3D pointAt(final double abscissa) { return new Vector3D(1.0, zero, abscissa, direction); } - /** Transform a space point into a sub-space point. - * @param vector n-dimension point of the space - * @return (n-1)-dimension point of the sub-space corresponding to - * the specified space point - */ - public Vector1D toSubSpace(Vector vector) { - return toSubSpace((Point) vector); - } - - /** Transform a sub-space point into a space point. - * @param vector (n-1)-dimension point of the sub-space - * @return n-dimension point of the space corresponding to the - * specified sub-space point - */ - public Vector3D toSpace(Vector vector) { - return toSpace((Point) vector); - } - /** {@inheritDoc} * @see #getAbscissa(Vector3D) */ @Override - public Vector1D toSubSpace(final Point point) { - return new Vector1D(getAbscissa((Vector3D) point)); + public Vector1D toSubSpace(final Vector3D point) { + return new Vector1D(getAbscissa(point)); } /** {@inheritDoc} * @see #pointAt(double) */ @Override - public Vector3D toSpace(final Point point) { - return pointAt(((Vector1D) point).getX()); + public Vector3D toSpace(final Vector1D point) { + return pointAt(point.getX()); } /** Check if the instance is similar to another line. diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/threed/OutlineExtractor.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/threed/OutlineExtractor.java index 6004f5d94..57ee92b23 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/threed/OutlineExtractor.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/threed/OutlineExtractor.java @@ -23,7 +23,6 @@ import java.util.ArrayList; -import org.hipparchus.geometry.Point; import org.hipparchus.geometry.euclidean.twod.Euclidean2D; import org.hipparchus.geometry.euclidean.twod.PolygonsSet; import org.hipparchus.geometry.euclidean.twod.Vector2D; @@ -123,7 +122,7 @@ private boolean pointIsBetween(final Vector2D[] loop, final int n, final int i) } /** Visitor projecting the boundary facets on a plane. */ - private class BoundaryProjector implements BSPTreeVisitor { + private class BoundaryProjector implements BSPTreeVisitor { /** Projection of the polyhedrons set on the plane. */ private PolygonsSet projected; @@ -135,22 +134,22 @@ private class BoundaryProjector implements BSPTreeVisitor { * @param tolerance tolerance below which points are considered identical */ BoundaryProjector(final double tolerance) { - this.projected = new PolygonsSet(new BSPTree(Boolean.FALSE), tolerance); + this.projected = new PolygonsSet(new BSPTree<>(Boolean.FALSE), tolerance); this.tolerance = tolerance; } /** {@inheritDoc} */ @Override - public Order visitOrder(final BSPTree node) { + public Order visitOrder(final BSPTree node) { return Order.MINUS_SUB_PLUS; } /** {@inheritDoc} */ @Override - public void visitInternalNode(final BSPTree node) { + public void visitInternalNode(final BSPTree node) { @SuppressWarnings("unchecked") - final BoundaryAttribute attribute = - (BoundaryAttribute) node.getAttribute(); + final BoundaryAttribute attribute = + (BoundaryAttribute) node.getAttribute(); if (attribute.getPlusOutside() != null) { addContribution(attribute.getPlusOutside()); } @@ -161,17 +160,17 @@ public void visitInternalNode(final BSPTree node) { /** {@inheritDoc} */ @Override - public void visitLeafNode(final BSPTree node) { + public void visitLeafNode(final BSPTree node) { } /** Add he contribution of a boundary facet. * @param facet boundary facet */ - private void addContribution(final SubHyperplane facet) { + private void addContribution(final SubHyperplane facet) { // extract the vertices of the facet - final AbstractSubHyperplane absFacet = - (AbstractSubHyperplane) facet; + final AbstractSubHyperplane absFacet = + (AbstractSubHyperplane) facet; final Plane plane = (Plane) facet.getHyperplane(); final double scal = plane.getNormal().dotProduct(w); @@ -205,21 +204,21 @@ private void addContribution(final SubHyperplane facet) { } // compute the projection of the facet in the outline plane - final ArrayList> edges = new ArrayList<>(); + final ArrayList> edges = new ArrayList<>(); for (Vector2D[] loop : vertices) { final boolean closed = loop[0] != null; int previous = closed ? (loop.length - 1) : 1; - final Vector3D previous3D = plane.toSpace((Point) loop[previous]); + final Vector3D previous3D = plane.toSpace(loop[previous]); int current = (previous + 1) % loop.length; Vector2D pPoint = new Vector2D(previous3D.dotProduct(u), previous3D.dotProduct(v)); while (current < loop.length) { - final Vector3D current3D = plane.toSpace((Point) loop[current]); + final Vector3D current3D = plane.toSpace(loop[current]); final Vector2D cPoint = new Vector2D(current3D.dotProduct(u), current3D.dotProduct(v)); final org.hipparchus.geometry.euclidean.twod.Line line = new org.hipparchus.geometry.euclidean.twod.Line(pPoint, cPoint, tolerance); - SubHyperplane edge = line.wholeHyperplane(); + SubHyperplane edge = line.wholeHyperplane(); if (closed || (previous != 1)) { // the previous point is a real vertex @@ -249,7 +248,7 @@ private void addContribution(final SubHyperplane facet) { final PolygonsSet projectedFacet = new PolygonsSet(edges, tolerance); // add the contribution of the facet to the global outline - projected = (PolygonsSet) new RegionFactory().union(projected, projectedFacet); + projected = (PolygonsSet) new RegionFactory().union(projected, projectedFacet); } } diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/threed/Plane.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/threed/Plane.java index 835ef48e3..dfba976b8 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/threed/Plane.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/threed/Plane.java @@ -23,9 +23,6 @@ import org.hipparchus.exception.LocalizedCoreFormats; import org.hipparchus.exception.MathRuntimeException; -import org.hipparchus.geometry.Point; -import org.hipparchus.geometry.Vector; -import org.hipparchus.geometry.euclidean.oned.Euclidean1D; import org.hipparchus.geometry.euclidean.oned.Vector1D; import org.hipparchus.geometry.euclidean.twod.Euclidean2D; import org.hipparchus.geometry.euclidean.twod.PolygonsSet; @@ -37,7 +34,9 @@ /** The class represent planes in a three dimensional space. */ -public class Plane implements Hyperplane, Embedding { +public class Plane + implements Hyperplane, + Embedding { /** Offset of the origin with respect to the plane. */ private double originOffset; @@ -180,8 +179,8 @@ public Vector3D getOrigin() { } /** Get the normalized normal vector. - *

The frame defined by ({@link #getU getU}, {@link #getV getV}, - * {@link #getNormal getNormal}) is a rigth-handed orthonormalized + *

The frame defined by ({@link #getU() getU()}, {@link #getV() getV()}, + * {@code getNormal()}) is a right-handed orthonormalized * frame).

* @return normalized normal vector * @see #getU @@ -192,8 +191,8 @@ public Vector3D getNormal() { } /** Get the plane first canonical vector. - *

The frame defined by ({@link #getU getU}, {@link #getV getV}, - * {@link #getNormal getNormal}) is a rigth-handed orthonormalized + *

The frame defined by ({@code getU()}, {@link #getV() getV()}, + * {@link #getNormal() getNormal()}) is a right-handed orthonormalized * frame).

* @return normalized first canonical vector * @see #getV @@ -204,8 +203,8 @@ public Vector3D getU() { } /** Get the plane second canonical vector. - *

The frame defined by ({@link #getU getU}, {@link #getV getV}, - * {@link #getNormal getNormal}) is a rigth-handed orthonormalized + *

The frame defined by ({@link #getU() getU()}, {@code getV()}, + * {@link #getNormal() getNormal()}) is a right-handed orthonormalized * frame).

* @return normalized second canonical vector * @see #getU @@ -218,7 +217,7 @@ public Vector3D getV() { /** {@inheritDoc} */ @Override - public Point project(Point point) { + public Vector3D project(Vector3D point) { return toSpace(toSubSpace(point)); } @@ -248,24 +247,6 @@ public void revertSelf() { originOffset = -originOffset; } - /** Transform a space point into a sub-space point. - * @param vector n-dimension point of the space - * @return (n-1)-dimension point of the sub-space corresponding to - * the specified space point - */ - public Vector2D toSubSpace(Vector vector) { - return toSubSpace((Point) vector); - } - - /** Transform a sub-space point into a space point. - * @param vector (n-1)-dimension point of the sub-space - * @return n-dimension point of the space corresponding to the - * specified sub-space point - */ - public Vector3D toSpace(Vector vector) { - return toSpace((Point) vector); - } - /** Transform a 3D space point into an in-plane point. * @param point point of the space (must be a {@link Vector3D * Vector3D} instance) @@ -274,9 +255,8 @@ public Vector3D toSpace(Vector vector) { * @see #toSpace */ @Override - public Vector2D toSubSpace(final Point point) { - final Vector3D p3D = (Vector3D) point; - return new Vector2D(p3D.dotProduct(u), p3D.dotProduct(v)); + public Vector2D toSubSpace(final Vector3D point) { + return new Vector2D(point.dotProduct(u), point.dotProduct(v)); } /** Transform an in-plane point into a 3D space point. @@ -286,9 +266,8 @@ public Vector2D toSubSpace(final Point point) { * @see #toSubSpace */ @Override - public Vector3D toSpace(final Point point) { - final Vector2D p2D = (Vector2D) point; - return new Vector3D(p2D.getX(), u, p2D.getY(), v, -originOffset, w); + public Vector3D toSpace(final Vector2D point) { + return new Vector3D(point.getX(), u, point.getY(), v, -originOffset, w); } /** Get one point from the 3D-space. @@ -363,7 +342,7 @@ public Vector3D intersection(final Line line) { if (FastMath.abs(dot) < 1.0e-10) { return null; } - final Vector3D point = line.toSpace((Point) Vector1D.ZERO); + final Vector3D point = line.toSpace(Vector1D.ZERO); final double k = -(originOffset + w.dotProduct(point)) / dot; return new Vector3D(1.0, point, k, direction); } @@ -435,7 +414,7 @@ public SubPlane wholeHyperplane() { /** {@inheritDoc} */ @Override public SubPlane emptyHyperplane() { - return new SubPlane(this, new RegionFactory().getComplement(new PolygonsSet(tolerance))); + return new SubPlane(this, new RegionFactory().getComplement(new PolygonsSet(tolerance))); } /** Build a region covering the whole space. @@ -469,14 +448,6 @@ public double getOffset(final Plane plane) { return originOffset + (sameOrientationAs(plane) ? -plane.originOffset : plane.originOffset); } - /** Get the offset (oriented distance) of a vector. - * @param vector vector to check - * @return offset of the vector - */ - public double getOffset(Vector vector) { - return getOffset((Point) vector); - } - /** Get the offset (oriented distance) of a point. *

The offset is 0 if the point is on the underlying hyperplane, * it is positive if the point is on one particular side of the @@ -486,8 +457,8 @@ public double getOffset(Vector vector) { * @return offset of the point */ @Override - public double getOffset(final Point point) { - return ((Vector3D) point).dotProduct(w) + originOffset; + public double getOffset(final Vector3D point) { + return point.dotProduct(w) + originOffset; } /** Check if the instance has the same orientation as another hyperplane. @@ -496,7 +467,7 @@ public double getOffset(final Point point) { * the same orientation */ @Override - public boolean sameOrientationAs(final Hyperplane other) { + public boolean sameOrientationAs(final Hyperplane other) { return (((Plane) other).w).dotProduct(w) > 0.0; } diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/threed/PolyhedronsSet.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/threed/PolyhedronsSet.java index df70297ec..aadab7bd2 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/threed/PolyhedronsSet.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/threed/PolyhedronsSet.java @@ -32,6 +32,7 @@ import org.hipparchus.geometry.LocalizedGeometryFormats; import org.hipparchus.geometry.Point; import org.hipparchus.geometry.euclidean.oned.Euclidean1D; +import org.hipparchus.geometry.euclidean.oned.Vector1D; import org.hipparchus.geometry.euclidean.twod.Euclidean2D; import org.hipparchus.geometry.euclidean.twod.PolygonsSet; import org.hipparchus.geometry.euclidean.twod.SubLine; @@ -49,7 +50,7 @@ /** This class represents a 3D region: a set of polyhedrons. */ -public class PolyhedronsSet extends AbstractRegion { +public class PolyhedronsSet extends AbstractRegion { /** Build a polyhedrons set representing the whole real line. * @param tolerance tolerance below which points are considered identical @@ -78,7 +79,7 @@ public PolyhedronsSet(final double tolerance) { * @param tree inside/outside BSP tree representing the region * @param tolerance tolerance below which points are considered identical */ - public PolyhedronsSet(final BSPTree tree, final double tolerance) { + public PolyhedronsSet(final BSPTree tree, final double tolerance) { super(tree, tolerance); } @@ -102,7 +103,7 @@ public PolyhedronsSet(final BSPTree tree, final double tolerance) { * collection of {@link SubHyperplane SubHyperplane} objects * @param tolerance tolerance below which points are considered identical */ - public PolyhedronsSet(final Collection> boundary, + public PolyhedronsSet(final Collection> boundary, final double tolerance) { super(boundary, tolerance); } @@ -170,13 +171,13 @@ public PolyhedronsSet(final double xMin, final double xMax, * @param tolerance tolerance below which points are considered identical * @return boundary tree */ - private static BSPTree buildBoundary(final double xMin, final double xMax, - final double yMin, final double yMax, - final double zMin, final double zMax, - final double tolerance) { + private static BSPTree buildBoundary(final double xMin, final double xMax, + final double yMin, final double yMax, + final double zMin, final double zMax, + final double tolerance) { if ((xMin >= xMax - tolerance) || (yMin >= yMax - tolerance) || (zMin >= zMax - tolerance)) { // too thin box, build an empty polygons set - return new BSPTree(Boolean.FALSE); + return new BSPTree<>(Boolean.FALSE); } final Plane pxMin = new Plane(new Vector3D(xMin, 0, 0), Vector3D.MINUS_I, tolerance); final Plane pxMax = new Plane(new Vector3D(xMax, 0, 0), Vector3D.PLUS_I, tolerance); @@ -184,8 +185,8 @@ private static BSPTree buildBoundary(final double xMin, final doubl final Plane pyMax = new Plane(new Vector3D(0, yMax, 0), Vector3D.PLUS_J, tolerance); final Plane pzMin = new Plane(new Vector3D(0, 0, zMin), Vector3D.MINUS_K, tolerance); final Plane pzMax = new Plane(new Vector3D(0, 0, zMax), Vector3D.PLUS_K, tolerance); - final Region boundary = - new RegionFactory().buildConvex(pxMin, pxMax, pyMin, pyMax, pzMin, pzMax); + final Region boundary = + new RegionFactory().buildConvex(pxMin, pxMax, pyMin, pyMax, pzMin, pzMax); return boundary.getTree(false); } @@ -196,9 +197,9 @@ private static BSPTree buildBoundary(final double xMin, final doubl * @return boundary as a list of sub-hyperplanes * @exception MathIllegalArgumentException if some basic sanity checks fail */ - private static List> buildBoundary(final List vertices, - final List facets, - final double tolerance) { + private static List> buildBoundary(final List vertices, + final List facets, + final double tolerance) { // check vertices distances for (int i = 0; i < vertices.size() - 1; ++i) { @@ -239,7 +240,7 @@ private static List> buildBoundary(final List> boundary = new ArrayList<>(); + final List> boundary = new ArrayList<>(); for (final int[] facet : facets) { @@ -357,7 +358,7 @@ private static int[][] successors(final List vertices, final List tree) { + public PolyhedronsSet buildNew(final BSPTree tree) { return new PolyhedronsSet(tree, getTolerance()); } @@ -390,7 +391,7 @@ public BRep getBRep() throws MathRuntimeException { } /** Visitor extracting BRep. */ - private static class BRepExtractor implements BSPTreeVisitor { + private static class BRepExtractor implements BSPTreeVisitor { /** Tolerance for vertices identification. */ private final double tolerance; @@ -419,16 +420,16 @@ public BRep getBRep() { /** {@inheritDoc} */ @Override - public Order visitOrder(final BSPTree node) { + public Order visitOrder(final BSPTree node) { return Order.MINUS_SUB_PLUS; } /** {@inheritDoc} */ @Override - public void visitInternalNode(final BSPTree node) { + public void visitInternalNode(final BSPTree node) { @SuppressWarnings("unchecked") - final BoundaryAttribute attribute = - (BoundaryAttribute) node.getAttribute(); + final BoundaryAttribute attribute = + (BoundaryAttribute) node.getAttribute(); if (attribute.getPlusOutside() != null) { addContribution(attribute.getPlusOutside(), false); } @@ -439,15 +440,15 @@ public void visitInternalNode(final BSPTree node) { /** {@inheritDoc} */ @Override - public void visitLeafNode(final BSPTree node) { + public void visitLeafNode(final BSPTree node) { } - /** Add he contribution of a boundary facet. + /** Add the contribution of a boundary facet. * @param facet boundary facet * @param reversed if true, the facet has the inside on its plus side * @exception MathRuntimeException if facet is unbounded */ - private void addContribution(final SubHyperplane facet, final boolean reversed) + private void addContribution(final SubHyperplane facet, final boolean reversed) throws MathRuntimeException { final Plane plane = (Plane) facet.getHyperplane(); @@ -504,36 +505,36 @@ protected void computeGeometricalProperties() { // the polyhedrons set as a finite outside // surrounded by an infinite inside setSize(Double.POSITIVE_INFINITY); - setBarycenter((Point) Vector3D.NaN); + setBarycenter(Vector3D.NaN); } else { // the polyhedrons set is finite, apply the remaining scaling factors setSize(getSize() / 3.0); - setBarycenter((Point) new Vector3D(1.0 / (4 * getSize()), (Vector3D) getBarycenter())); + setBarycenter(new Vector3D(1.0 / (4 * getSize()), getBarycenter())); } } /** Visitor computing geometrical properties. */ - private class FacetsContributionVisitor implements BSPTreeVisitor { + private class FacetsContributionVisitor implements BSPTreeVisitor { /** Simple constructor. */ FacetsContributionVisitor() { setSize(0); - setBarycenter((Point) new Vector3D(0, 0, 0)); + setBarycenter(new Vector3D(0, 0, 0)); } /** {@inheritDoc} */ @Override - public Order visitOrder(final BSPTree node) { + public Order visitOrder(final BSPTree node) { return Order.MINUS_SUB_PLUS; } /** {@inheritDoc} */ @Override - public void visitInternalNode(final BSPTree node) { + public void visitInternalNode(final BSPTree node) { @SuppressWarnings("unchecked") - final BoundaryAttribute attribute = - (BoundaryAttribute) node.getAttribute(); + final BoundaryAttribute attribute = + (BoundaryAttribute) node.getAttribute(); if (attribute.getPlusOutside() != null) { addContribution(attribute.getPlusOutside(), false); } @@ -544,21 +545,21 @@ public void visitInternalNode(final BSPTree node) { /** {@inheritDoc} */ @Override - public void visitLeafNode(final BSPTree node) { + public void visitLeafNode(final BSPTree node) { } /** Add he contribution of a boundary facet. * @param facet boundary facet * @param reversed if true, the facet has the inside on its plus side */ - private void addContribution(final SubHyperplane facet, final boolean reversed) { + private void addContribution(final SubHyperplane facet, final boolean reversed) { - final Region polygon = ((SubPlane) facet).getRemainingRegion(); + final Region polygon = ((SubPlane) facet).getRemainingRegion(); final double area = polygon.getSize(); if (Double.isInfinite(area)) { setSize(Double.POSITIVE_INFINITY); - setBarycenter((Point) Vector3D.NaN); + setBarycenter(Vector3D.NaN); } else { final Plane plane = (Plane) facet.getHyperplane(); @@ -569,7 +570,7 @@ private void addContribution(final SubHyperplane facet, final boole } setSize(getSize() + scaled); - setBarycenter((Point) new Vector3D(1.0, (Vector3D) getBarycenter(), scaled, facetB)); + setBarycenter(new Vector3D(1.0, getBarycenter(), scaled, facetB)); } @@ -584,7 +585,7 @@ private void addContribution(final SubHyperplane facet, final boole * given point, or null if the line does not intersect any * sub-hyperplane */ - public SubHyperplane firstIntersection(final Vector3D point, final Line line) { + public SubHyperplane firstIntersection(final Vector3D point, final Line line) { return recurseFirstIntersection(getTree(true), point, line); } @@ -596,23 +597,22 @@ public SubHyperplane firstIntersection(final Vector3D point, final * given point, or null if the line does not intersect any * sub-hyperplane */ - private SubHyperplane recurseFirstIntersection(final BSPTree node, - final Vector3D point, - final Line line) { + private SubHyperplane recurseFirstIntersection(final BSPTree node, + final Vector3D point, final Line line) { - final SubHyperplane cut = node.getCut(); + final SubHyperplane cut = node.getCut(); if (cut == null) { return null; } - final BSPTree minus = node.getMinus(); - final BSPTree plus = node.getPlus(); + final BSPTree minus = node.getMinus(); + final BSPTree plus = node.getPlus(); final Plane plane = (Plane) cut.getHyperplane(); // establish search order - final double offset = plane.getOffset((Point) point); + final double offset = plane.getOffset(point); final boolean in = FastMath.abs(offset) < getTolerance(); - final BSPTree near; - final BSPTree far; + final BSPTree near; + final BSPTree far; if (offset < 0) { near = minus; far = plus; @@ -623,14 +623,14 @@ private SubHyperplane recurseFirstIntersection(final BSPTree facet = boundaryFacet(point, node); + final SubHyperplane facet = boundaryFacet(point, node); if (facet != null) { return facet; } } // search in the near branch - final SubHyperplane crossed = recurseFirstIntersection(near, point, line); + final SubHyperplane crossed = recurseFirstIntersection(near, point, line); if (crossed != null) { return crossed; } @@ -639,7 +639,7 @@ private SubHyperplane recurseFirstIntersection(final BSPTree line.getAbscissa(point)) { - final SubHyperplane facet = boundaryFacet(hit3D, node); + final SubHyperplane facet = boundaryFacet(hit3D, node); if (facet != null) { return facet; } @@ -657,12 +657,12 @@ private SubHyperplane recurseFirstIntersection(final BSPTree boundaryFacet(final Vector3D point, - final BSPTree node) { - final Vector2D point2D = ((Plane) node.getCut().getHyperplane()).toSubSpace((Point) point); + private SubHyperplane boundaryFacet(final Vector3D point, + final BSPTree node) { + final Vector2D point2D = ((Plane) node.getCut().getHyperplane()).toSubSpace(point); @SuppressWarnings("unchecked") - final BoundaryAttribute attribute = - (BoundaryAttribute) node.getAttribute(); + final BoundaryAttribute attribute = + (BoundaryAttribute) node.getAttribute(); if ((attribute.getPlusOutside() != null) && (((SubPlane) attribute.getPlusOutside()).getRemainingRegion().checkPoint(point2D) != Location.OUTSIDE)) { return attribute.getPlusOutside(); @@ -685,7 +685,8 @@ public PolyhedronsSet rotate(final Vector3D center, final Rotation rotation) { } /** 3D rotation as a Transform. */ - private static class RotationTransform implements Transform { + private static class RotationTransform + implements Transform { /** Center point of the rotation. */ private final Vector3D center; @@ -697,7 +698,7 @@ private static class RotationTransform implements Transform cachedTransform; + private Transform cachedTransform; /** Build a rotation transform. * @param center center point of the rotation @@ -710,42 +711,42 @@ private static class RotationTransform implements Transform point) { - final Vector3D delta = ((Vector3D) point).subtract(center); + public Vector3D apply(final Vector3D point) { + final Vector3D delta = point.subtract(center); return new Vector3D(1.0, center, 1.0, rotation.applyTo(delta)); } /** {@inheritDoc} */ @Override - public Plane apply(final Hyperplane hyperplane) { + public Plane apply(final Hyperplane hyperplane) { return ((Plane) hyperplane).rotate(center, rotation); } /** {@inheritDoc} */ @Override - public SubHyperplane apply(final SubHyperplane sub, - final Hyperplane original, - final Hyperplane transformed) { + public SubHyperplane apply(final SubHyperplane sub, + final Hyperplane original, + final Hyperplane transformed) { if (original != cachedOriginal) { // we have changed hyperplane, reset the in-hyperplane transform final Plane oPlane = (Plane) original; final Plane tPlane = (Plane) transformed; final Vector3D p00 = oPlane.getOrigin(); - final Vector3D p10 = oPlane.toSpace((Point) new Vector2D(1.0, 0.0)); - final Vector3D p01 = oPlane.toSpace((Point) new Vector2D(0.0, 1.0)); - final Vector2D tP00 = tPlane.toSubSpace((Point) apply(p00)); - final Vector2D tP10 = tPlane.toSubSpace((Point) apply(p10)); - final Vector2D tP01 = tPlane.toSubSpace((Point) apply(p01)); + final Vector3D p10 = oPlane.toSpace(new Vector2D(1.0, 0.0)); + final Vector3D p01 = oPlane.toSpace(new Vector2D(0.0, 1.0)); + final Vector2D tP00 = tPlane.toSubSpace(apply(p00)); + final Vector2D tP10 = tPlane.toSubSpace(apply(p10)); + final Vector2D tP01 = tPlane.toSubSpace(apply(p01)); cachedOriginal = (Plane) original; cachedTransform = org.hipparchus.geometry.euclidean.twod.Line.getTransform(tP10.getX() - tP00.getX(), - tP10.getY() - tP00.getY(), - tP01.getX() - tP00.getX(), - tP01.getY() - tP00.getY(), - tP00.getX(), - tP00.getY()); + tP10.getY() - tP00.getY(), + tP01.getX() - tP00.getX(), + tP01.getY() - tP00.getY(), + tP00.getX(), + tP00.getY()); } return ((SubLine) sub).applyTransform(cachedTransform); @@ -763,7 +764,8 @@ public PolyhedronsSet translate(final Vector3D translation) { } /** 3D translation as a transform. */ - private static class TranslationTransform implements Transform { + private static class TranslationTransform + implements Transform { /** Translation vector. */ private final Vector3D translation; @@ -772,7 +774,7 @@ private static class TranslationTransform implements Transform cachedTransform; + private Transform cachedTransform; /** Build a translation transform. * @param translation translation vector @@ -783,27 +785,27 @@ private static class TranslationTransform implements Transform point) { - return new Vector3D(1.0, (Vector3D) point, 1.0, translation); + public Vector3D apply(final Vector3D point) { + return new Vector3D(1.0, point, 1.0, translation); } /** {@inheritDoc} */ @Override - public Plane apply(final Hyperplane hyperplane) { + public Plane apply(final Hyperplane hyperplane) { return ((Plane) hyperplane).translate(translation); } /** {@inheritDoc} */ @Override - public SubHyperplane apply(final SubHyperplane sub, - final Hyperplane original, - final Hyperplane transformed) { + public SubHyperplane apply(final SubHyperplane sub, + final Hyperplane original, + final Hyperplane transformed) { if (original != cachedOriginal) { // we have changed hyperplane, reset the in-hyperplane transform final Plane oPlane = (Plane) original; final Plane tPlane = (Plane) transformed; - final Vector2D shift = tPlane.toSubSpace((Point) apply(oPlane.getOrigin())); + final Vector2D shift = tPlane.toSubSpace(apply(oPlane.getOrigin())); cachedOriginal = (Plane) original; cachedTransform = diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/threed/SubLine.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/threed/SubLine.java index 76541ca9a..ce68d8a56 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/threed/SubLine.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/threed/SubLine.java @@ -25,8 +25,6 @@ import java.util.List; import org.hipparchus.exception.MathIllegalArgumentException; -import org.hipparchus.geometry.Point; -import org.hipparchus.geometry.euclidean.oned.Euclidean1D; import org.hipparchus.geometry.euclidean.oned.Interval; import org.hipparchus.geometry.euclidean.oned.IntervalsSet; import org.hipparchus.geometry.euclidean.oned.Vector1D; @@ -91,8 +89,8 @@ public List getSegments() { final List segments = new ArrayList<>(list.size()); for (final Interval interval : list) { - final Vector3D start = line.toSpace((Point) new Vector1D(interval.getInf())); - final Vector3D end = line.toSpace((Point) new Vector1D(interval.getSup())); + final Vector3D start = line.toSpace(new Vector1D(interval.getInf())); + final Vector3D end = line.toSpace(new Vector1D(interval.getSup())); segments.add(new Segment(start, end, line)); } @@ -123,10 +121,10 @@ public Vector3D intersection(final SubLine subLine, final boolean includeEndPoin } // check location of point with respect to first sub-line - Location loc1 = remainingRegion.checkPoint((Point) line.toSubSpace((Point) v1D)); + Location loc1 = remainingRegion.checkPoint(line.toSubSpace(v1D)); // check location of point with respect to second sub-line - Location loc2 = subLine.remainingRegion.checkPoint((Point) subLine.line.toSubSpace((Point) v1D)); + Location loc2 = subLine.remainingRegion.checkPoint(subLine.line.toSubSpace(v1D)); if (includeEndPoints) { return ((loc1 != Location.OUTSIDE) && (loc2 != Location.OUTSIDE)) ? v1D : null; @@ -146,9 +144,7 @@ public Vector3D intersection(final SubLine subLine, final boolean includeEndPoin private static IntervalsSet buildIntervalSet(final Vector3D start, final Vector3D end, final double tolerance) throws MathIllegalArgumentException { final Line line = new Line(start, end, tolerance); - return new IntervalsSet(line.toSubSpace((Point) start).getX(), - line.toSubSpace((Point) end).getX(), - tolerance); + return new IntervalsSet(line.toSubSpace(start).getX(), line.toSubSpace(end).getX(), tolerance); } } diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/threed/SubPlane.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/threed/SubPlane.java index fc711cd27..1d4ef66e6 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/threed/SubPlane.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/threed/SubPlane.java @@ -21,8 +21,6 @@ */ package org.hipparchus.geometry.euclidean.threed; -import org.hipparchus.geometry.Point; -import org.hipparchus.geometry.euclidean.oned.Euclidean1D; import org.hipparchus.geometry.euclidean.oned.Vector1D; import org.hipparchus.geometry.euclidean.twod.Euclidean2D; import org.hipparchus.geometry.euclidean.twod.PolygonsSet; @@ -35,21 +33,22 @@ /** This class represents a sub-hyperplane for {@link Plane}. */ -public class SubPlane extends AbstractSubHyperplane { +public class SubPlane extends AbstractSubHyperplane { /** Simple constructor. * @param hyperplane underlying hyperplane * @param remainingRegion remaining region of the hyperplane */ - public SubPlane(final Hyperplane hyperplane, - final Region remainingRegion) { + public SubPlane(final Hyperplane hyperplane, + final Region remainingRegion) { super(hyperplane, remainingRegion); } /** {@inheritDoc} */ @Override - protected AbstractSubHyperplane buildNew(final Hyperplane hyperplane, - final Region remainingRegion) { + protected AbstractSubHyperplane + buildNew(final Hyperplane hyperplane, + final Region remainingRegion) { return new SubPlane(hyperplane, remainingRegion); } @@ -60,7 +59,7 @@ protected AbstractSubHyperplane buildNew(final Hyperpl * instance on the minus side of the instance */ @Override - public SplitSubHyperplane split(Hyperplane hyperplane) { + public SplitSubHyperplane split(Hyperplane hyperplane) { final Plane otherPlane = (Plane) hyperplane; final Plane thisPlane = (Plane) getHyperplane(); @@ -71,37 +70,37 @@ public SplitSubHyperplane split(Hyperplane hyperplane) // the hyperplanes are parallel final double global = otherPlane.getOffset(thisPlane); if (global < -tolerance) { - return new SplitSubHyperplane(null, this); + return new SplitSubHyperplane<>(null, this); } else if (global > tolerance) { - return new SplitSubHyperplane(this, null); + return new SplitSubHyperplane<>(this, null); } else { - return new SplitSubHyperplane(null, null); + return new SplitSubHyperplane<>(null, null); } } // the hyperplanes do intersect - Vector2D p = thisPlane.toSubSpace((Point) inter.toSpace((Point) Vector1D.ZERO)); - Vector2D q = thisPlane.toSubSpace((Point) inter.toSpace((Point) Vector1D.ONE)); + Vector2D p = thisPlane.toSubSpace(inter.toSpace(Vector1D.ZERO)); + Vector2D q = thisPlane.toSubSpace(inter.toSpace(Vector1D.ONE)); Vector3D crossP = Vector3D.crossProduct(inter.getDirection(), thisPlane.getNormal()); if (crossP.dotProduct(otherPlane.getNormal()) < 0) { final Vector2D tmp = p; p = q; q = tmp; } - final SubHyperplane l2DMinus = + final SubHyperplane l2DMinus = new org.hipparchus.geometry.euclidean.twod.Line(p, q, tolerance).wholeHyperplane(); - final SubHyperplane l2DPlus = + final SubHyperplane l2DPlus = new org.hipparchus.geometry.euclidean.twod.Line(q, p, tolerance).wholeHyperplane(); - final BSPTree splitTree = getRemainingRegion().getTree(false).split(l2DMinus); - final BSPTree plusTree = getRemainingRegion().isEmpty(splitTree.getPlus()) ? - new BSPTree<>(Boolean.FALSE) : - new BSPTree<>(l2DPlus, new BSPTree<>(Boolean.FALSE), - splitTree.getPlus(), null); + final BSPTree splitTree = getRemainingRegion().getTree(false).split(l2DMinus); + final BSPTree plusTree = getRemainingRegion().isEmpty(splitTree.getPlus()) ? + new BSPTree<>(Boolean.FALSE) : + new BSPTree<>(l2DPlus, new BSPTree<>(Boolean.FALSE), + splitTree.getPlus(), null); - final BSPTree minusTree = getRemainingRegion().isEmpty(splitTree.getMinus()) ? - new BSPTree<>(Boolean.FALSE) : - new BSPTree<>(l2DMinus, new BSPTree<>(Boolean.FALSE), + final BSPTree minusTree = getRemainingRegion().isEmpty(splitTree.getMinus()) ? + new BSPTree<>(Boolean.FALSE) : + new BSPTree<>(l2DMinus, new BSPTree<>(Boolean.FALSE), splitTree.getMinus(), null); return new SplitSubHyperplane<>(new SubPlane(thisPlane.copySelf(), new PolygonsSet(plusTree, tolerance)), diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/twod/Line.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/twod/Line.java index 7fcf9963d..18da61eca 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/twod/Line.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/twod/Line.java @@ -23,8 +23,6 @@ import org.hipparchus.exception.MathIllegalArgumentException; import org.hipparchus.geometry.LocalizedGeometryFormats; -import org.hipparchus.geometry.Point; -import org.hipparchus.geometry.Vector; import org.hipparchus.geometry.euclidean.oned.Euclidean1D; import org.hipparchus.geometry.euclidean.oned.IntervalsSet; import org.hipparchus.geometry.euclidean.oned.OrientedPoint; @@ -64,7 +62,9 @@ * right half plane is the set of points with positive offsets.

*/ -public class Line implements Hyperplane, Embedding { +public class Line + implements Hyperplane, + Embedding { /** Angle with respect to the abscissa axis. */ private double angle; @@ -225,35 +225,16 @@ public Line getReverse() { return reverse; } - /** Transform a space point into a sub-space point. - * @param vector n-dimension point of the space - * @return (n-1)-dimension point of the sub-space corresponding to - * the specified space point - */ - public Vector1D toSubSpace(Vector vector) { - return toSubSpace((Point) vector); - } - - /** Transform a sub-space point into a space point. - * @param vector (n-1)-dimension point of the sub-space - * @return n-dimension point of the space corresponding to the - * specified sub-space point - */ - public Vector2D toSpace(Vector vector) { - return toSpace((Point) vector); - } - /** {@inheritDoc} */ @Override - public Vector1D toSubSpace(final Point point) { - Vector2D p2 = (Vector2D) point; - return new Vector1D(MathArrays.linearCombination(cos, p2.getX(), sin, p2.getY())); + public Vector1D toSubSpace(final Vector2D point) { + return new Vector1D(MathArrays.linearCombination(cos, point.getX(), sin, point.getY())); } /** {@inheritDoc} */ @Override - public Vector2D toSpace(final Point point) { - final double abscissa = ((Vector1D) point).getX(); + public Vector2D toSpace(final Vector1D point) { + final double abscissa = point.getX(); return new Vector2D(MathArrays.linearCombination(abscissa, cos, -originOffset, sin), MathArrays.linearCombination(abscissa, sin, originOffset, cos)); } @@ -275,7 +256,7 @@ public Vector2D intersection(final Line other) { /** {@inheritDoc} */ @Override - public Point project(Point point) { + public Vector2D project(Vector2D point) { return toSpace(toSubSpace(point)); } @@ -295,7 +276,7 @@ public SubLine wholeHyperplane() { /** {@inheritDoc} */ @Override public SubLine emptyHyperplane() { - return new SubLine(this, new RegionFactory().getComplement(new IntervalsSet(tolerance))); + return new SubLine(this, new RegionFactory().getComplement(new IntervalsSet(tolerance))); } /** Build a region covering the whole space. @@ -322,24 +303,15 @@ public double getOffset(final Line line) { (MathArrays.linearCombination(cos, line.cos, sin, line.sin) > 0 ? -line.originOffset : line.originOffset); } - /** Get the offset (oriented distance) of a vector. - * @param vector vector to check - * @return offset of the vector - */ - public double getOffset(Vector vector) { - return getOffset((Point) vector); - } - /** {@inheritDoc} */ @Override - public double getOffset(final Point point) { - Vector2D p2 = (Vector2D) point; - return MathArrays.linearCombination(sin, p2.getX(), -cos, p2.getY(), 1.0, originOffset); + public double getOffset(final Vector2D point) { + return MathArrays.linearCombination(sin, point.getX(), -cos, point.getY(), 1.0, originOffset); } /** {@inheritDoc} */ @Override - public boolean sameOrientationAs(final Hyperplane other) { + public boolean sameOrientationAs(final Hyperplane other) { final Line otherL = (Line) other; return MathArrays.linearCombination(sin, otherL.sin, cos, otherL.cos) >= 0.0; } @@ -440,12 +412,12 @@ public void setOriginOffset(final double offset) { * SubHyperplane} instances * @exception MathIllegalArgumentException if the transform is non invertible */ - public static Transform getTransform(final double cXX, - final double cYX, - final double cXY, - final double cYY, - final double cX1, - final double cY1) + public static Transform getTransform(final double cXX, + final double cYX, + final double cXY, + final double cYY, + final double cX1, + final double cY1) throws MathIllegalArgumentException { return new LineTransform(cXX, cYX, cXY, cYY, cX1, cY1); } @@ -457,7 +429,8 @@ public static Transform getTransform(final double cXX, * applied to a large number of lines (for example to a large * polygon)./

*/ - private static class LineTransform implements Transform { + private static class LineTransform + implements Transform { /** Transform factor between input abscissa and output abscissa. */ private final double cXX; @@ -518,17 +491,16 @@ private static class LineTransform implements Transform point) { - final Vector2D p2D = (Vector2D) point; - final double x = p2D.getX(); - final double y = p2D.getY(); + public Vector2D apply(final Vector2D point) { + final double x = point.getX(); + final double y = point.getY(); return new Vector2D(MathArrays.linearCombination(cXX, x, cXY, y, cX1, 1), MathArrays.linearCombination(cYX, x, cYY, y, cY1, 1)); } /** {@inheritDoc} */ @Override - public Line apply(final Hyperplane hyperplane) { + public Line apply(final Hyperplane hyperplane) { final Line line = (Line) hyperplane; final double rOffset = MathArrays.linearCombination(c1X, line.cos, c1Y, line.sin, c11, line.originOffset); final double rCos = MathArrays.linearCombination(cXX, line.cos, cXY, line.sin); @@ -541,9 +513,9 @@ public Line apply(final Hyperplane hyperplane) { /** {@inheritDoc} */ @Override - public SubHyperplane apply(final SubHyperplane sub, - final Hyperplane original, - final Hyperplane transformed) { + public SubHyperplane apply(final SubHyperplane sub, + final Hyperplane original, + final Hyperplane transformed) { final OrientedPoint op = (OrientedPoint) sub.getHyperplane(); final Line originalLine = (Line) original; final Line transformedLine = (Line) transformed; diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/twod/PolygonsSet.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/twod/PolygonsSet.java index 37a8748f1..79a6ad7d4 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/twod/PolygonsSet.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/twod/PolygonsSet.java @@ -27,7 +27,6 @@ import java.util.List; import java.util.Map; -import org.hipparchus.geometry.Point; import org.hipparchus.geometry.euclidean.oned.Euclidean1D; import org.hipparchus.geometry.euclidean.oned.Interval; import org.hipparchus.geometry.euclidean.oned.IntervalsSet; @@ -45,7 +44,7 @@ /** This class represents a 2D region: a set of polygons. */ -public class PolygonsSet extends AbstractRegion { +public class PolygonsSet extends AbstractRegion { /** Vertices organized as boundary loops. */ private Vector2D[][] vertices; @@ -77,7 +76,7 @@ public PolygonsSet(final double tolerance) { * @param tree inside/outside BSP tree representing the region * @param tolerance tolerance below which points are considered identical */ - public PolygonsSet(final BSPTree tree, final double tolerance) { + public PolygonsSet(final BSPTree tree, final double tolerance) { super(tree, tolerance); } @@ -102,7 +101,7 @@ public PolygonsSet(final BSPTree tree, final double tolerance) { * collection of {@link SubHyperplane SubHyperplane} objects * @param tolerance tolerance below which points are considered identical */ - public PolygonsSet(final Collection> boundary, final double tolerance) { + public PolygonsSet(final Collection> boundary, final double tolerance) { super(boundary, tolerance); } @@ -195,13 +194,13 @@ private static Line[] boxBoundary(final double xMin, final double xMax, * @param vertices vertices of the simple loop boundary * @return the BSP tree of the input vertices */ - private static BSPTree verticesToTree(final double hyperplaneThickness, - final Vector2D ... vertices) { + private static BSPTree verticesToTree(final double hyperplaneThickness, + final Vector2D ... vertices) { final int n = vertices.length; if (n == 0) { // the tree represents the whole space - return new BSPTree(Boolean.TRUE); + return new BSPTree<>(Boolean.TRUE); } // build the vertices @@ -230,7 +229,7 @@ private static BSPTree verticesToTree(final double hyperplaneThickn } // build the tree top-down - final BSPTree tree = new BSPTree<>(); + final BSPTree tree = new BSPTree<>(); insertEdges(hyperplaneThickness, tree, edges); return tree; @@ -297,7 +296,7 @@ private static Line supportingLine(final Vertex start, final Vertex end, * (excluding edges not belonging to the cell defined by this node) */ private static void insertEdges(final double hyperplaneThickness, - final BSPTree node, + final BSPTree node, final List edges) { // find an edge with an hyperplane that can be inserted in the node @@ -319,7 +318,7 @@ private static void insertEdges(final double hyperplaneThickness, if (inserted == null) { // no suitable edge was found, the node remains a leaf node // we need to set its inside/outside boolean indicator - final BSPTree parent = node.getParent(); + final BSPTree parent = node.getParent(); if (parent == null || node == parent.getMinus()) { node.setAttribute(Boolean.TRUE); } else { @@ -334,8 +333,8 @@ private static void insertEdges(final double hyperplaneThickness, final List minusList = new ArrayList<>(); for (final Edge edge : edges) { if (edge != inserted) { - final double startOffset = inserted.getLine().getOffset((Point) edge.getStart().getLocation()); - final double endOffset = inserted.getLine().getOffset((Point) edge.getEnd().getLocation()); + final double startOffset = inserted.getLine().getOffset(edge.getStart().getLocation()); + final double endOffset = inserted.getLine().getOffset(edge.getEnd().getLocation()); Side startSide = (FastMath.abs(startOffset) <= hyperplaneThickness) ? Side.HYPER : ((startOffset < 0) ? Side.MINUS : Side.PLUS); Side endSide = (FastMath.abs(endOffset) <= hyperplaneThickness) ? @@ -465,7 +464,7 @@ private static class Edge { private final Line line; /** Node whose cut hyperplane contains this edge. */ - private BSPTree node; + private BSPTree node; /** Build an edge not contained in any node yet. * @param start start vertex @@ -509,7 +508,7 @@ public Line getLine() { /** Set the node whose cut hyperplane contains this edge. * @param node node whose cut hyperplane contains this edge */ - public void setNode(final BSPTree node) { + public void setNode(final BSPTree node) { this.node = node; } @@ -517,7 +516,7 @@ public void setNode(final BSPTree node) { * @return node whose cut hyperplane contains this edge * (null if edge has not yet been inserted into the BSP tree) */ - public BSPTree getNode() { + public BSPTree getNode() { return node; } @@ -543,7 +542,7 @@ public Vertex split(final Line splitLine) { /** {@inheritDoc} */ @Override - public PolygonsSet buildNew(final BSPTree tree) { + public PolygonsSet buildNew(final BSPTree tree) { return new PolygonsSet(tree, getTolerance()); } @@ -554,19 +553,19 @@ protected void computeGeometricalProperties() { final Vector2D[][] v = getVertices(); if (v.length == 0) { - final BSPTree tree = getTree(false); + final BSPTree tree = getTree(false); if (tree.getCut() == null && (Boolean) tree.getAttribute()) { // the instance covers the whole space setSize(Double.POSITIVE_INFINITY); - setBarycenter((Point) Vector2D.NaN); + setBarycenter(Vector2D.NaN); } else { setSize(0); - setBarycenter((Point) new Vector2D(0, 0)); + setBarycenter(new Vector2D(0, 0)); } } else if (v[0][0] == null) { // there is at least one open-loop: the polygon is infinite setSize(Double.POSITIVE_INFINITY); - setBarycenter((Point) Vector2D.NaN); + setBarycenter(Vector2D.NaN); } else { // all loops are closed, we compute some integrals around the shape @@ -592,10 +591,10 @@ protected void computeGeometricalProperties() { if (sum < 0) { // the polygon as a finite outside surrounded by an infinite inside setSize(Double.POSITIVE_INFINITY); - setBarycenter((Point) Vector2D.NaN); + setBarycenter(Vector2D.NaN); } else { setSize(sum / 2); - setBarycenter((Point) new Vector2D(sumX / (3 * sum), sumY / (3 * sum))); + setBarycenter(new Vector2D(sumX / (3 * sum), sumY / (3 * sum))); } } @@ -673,8 +672,8 @@ public Vector2D[][] getVertices() { final Line line = loop.get(0).getLine(); vertices[i++] = new Vector2D[] { null, - line.toSpace((Point) new Vector1D(-Float.MAX_VALUE)), - line.toSpace((Point) new Vector1D(+Float.MAX_VALUE)) + line.toSpace(new Vector1D(-Float.MAX_VALUE)), + line.toSpace(new Vector1D(+Float.MAX_VALUE)) }; } else if (loop.get(0).getStart() == null) { // open loop with at least one real point @@ -684,10 +683,10 @@ public Vector2D[][] getVertices() { if (j == 0) { // null point and first dummy point - double x = segment.getLine().toSubSpace((Point) segment.getEnd()).getX(); + double x = segment.getLine().toSubSpace(segment.getEnd()).getX(); x -= FastMath.max(1.0, FastMath.abs(x / 2)); array[j++] = null; - array[j++] = segment.getLine().toSpace((Point) new Vector1D(x)); + array[j++] = segment.getLine().toSpace(new Vector1D(x)); } if (j < (array.length - 1)) { @@ -697,9 +696,9 @@ public Vector2D[][] getVertices() { if (j == (array.length - 1)) { // last dummy point - double x = segment.getLine().toSubSpace((Point) segment.getStart()).getX(); + double x = segment.getLine().toSubSpace(segment.getStart()).getX(); x += FastMath.max(1.0, FastMath.abs(x / 2)); - array[j++] = segment.getLine().toSpace((Point) new Vector1D(x)); + array[j++] = segment.getLine().toSpace(new Vector1D(x)); } } @@ -729,8 +728,8 @@ private int naturalFollowerConnections(final List segments) int connected = 0; for (final ConnectableSegment segment : segments) { if (segment.getNext() == null) { - final BSPTree node = segment.getNode(); - final BSPTree end = segment.getEndNode(); + final BSPTree node = segment.getNode(); + final BSPTree end = segment.getEndNode(); for (final ConnectableSegment candidateNext : segments) { if (candidateNext.getPrevious() == null && candidateNext.getNode() == end && @@ -755,8 +754,8 @@ private int splitEdgeConnections(final List segments) { int connected = 0; for (final ConnectableSegment segment : segments) { if (segment.getNext() == null) { - final Hyperplane hyperplane = segment.getNode().getCut().getHyperplane(); - final BSPTree end = segment.getEndNode(); + final Hyperplane hyperplane = segment.getNode().getCut().getHyperplane(); + final BSPTree end = segment.getEndNode(); for (final ConnectableSegment candidateNext : segments) { if (candidateNext.getPrevious() == null && candidateNext.getNode().getCut().getHyperplane() == hyperplane && @@ -889,13 +888,13 @@ private void filterSpuriousVertices(final List loop) { private static class ConnectableSegment extends Segment { /** Node containing segment. */ - private final BSPTree node; + private final BSPTree node; /** Node whose intersection with current node defines start point. */ - private final BSPTree startNode; + private final BSPTree startNode; /** Node whose intersection with current node defines end point. */ - private final BSPTree endNode; + private final BSPTree endNode; /** Previous segment. */ private ConnectableSegment previous; @@ -915,9 +914,9 @@ private static class ConnectableSegment extends Segment { * @param endNode node whose intersection with current node defines end point */ ConnectableSegment(final Vector2D start, final Vector2D end, final Line line, - final BSPTree node, - final BSPTree startNode, - final BSPTree endNode) { + final BSPTree node, + final BSPTree startNode, + final BSPTree endNode) { super(start, end, line); this.node = node; this.startNode = startNode; @@ -930,21 +929,21 @@ private static class ConnectableSegment extends Segment { /** Get the node containing segment. * @return node containing segment */ - public BSPTree getNode() { + public BSPTree getNode() { return node; } /** Get the node whose intersection with current node defines start point. * @return node whose intersection with current node defines start point */ - public BSPTree getStartNode() { + public BSPTree getStartNode() { return startNode; } /** Get the node whose intersection with current node defines end point. * @return node whose intersection with current node defines end point */ - public BSPTree getEndNode() { + public BSPTree getEndNode() { return endNode; } @@ -993,7 +992,7 @@ public boolean isProcessed() { } /** Visitor building segments. */ - private static class SegmentsBuilder implements BSPTreeVisitor { + private static class SegmentsBuilder implements BSPTreeVisitor { /** Tolerance for close nodes connection. */ private final double tolerance; @@ -1011,16 +1010,17 @@ private static class SegmentsBuilder implements BSPTreeVisitor { /** {@inheritDoc} */ @Override - public Order visitOrder(final BSPTree node) { + public Order visitOrder(final BSPTree node) { return Order.MINUS_SUB_PLUS; } /** {@inheritDoc} */ @Override - public void visitInternalNode(final BSPTree node) { + public void visitInternalNode(final BSPTree node) { @SuppressWarnings("unchecked") - final BoundaryAttribute attribute = (BoundaryAttribute) node.getAttribute(); - final Iterable> splitters = attribute.getSplitters(); + final BoundaryAttribute attribute = + (BoundaryAttribute) node.getAttribute(); + final Iterable> splitters = attribute.getSplitters(); if (attribute.getPlusOutside() != null) { addContribution(attribute.getPlusOutside(), node, splitters, false); } @@ -1031,7 +1031,7 @@ public void visitInternalNode(final BSPTree node) { /** {@inheritDoc} */ @Override - public void visitLeafNode(final BSPTree node) { + public void visitLeafNode(final BSPTree node) { } /** Add the contribution of a boundary facet. @@ -1040,25 +1040,25 @@ public void visitLeafNode(final BSPTree node) { * @param splitters splitters for the boundary facet * @param reversed if true, the facet has the inside on its plus side */ - private void addContribution(final SubHyperplane sub, - final BSPTree node, - final Iterable> splitters, + private void addContribution(final SubHyperplane sub, + final BSPTree node, + final Iterable> splitters, final boolean reversed) { - final AbstractSubHyperplane absSub = - (AbstractSubHyperplane) sub; + final AbstractSubHyperplane absSub = + (AbstractSubHyperplane) sub; final Line line = (Line) sub.getHyperplane(); final List intervals = ((IntervalsSet) absSub.getRemainingRegion()).asList(); for (final Interval i : intervals) { // find the 2D points final Vector2D startV = Double.isInfinite(i.getInf()) ? - null : (Vector2D) line.toSpace((Point) new Vector1D(i.getInf())); + null : line.toSpace(new Vector1D(i.getInf())); final Vector2D endV = Double.isInfinite(i.getSup()) ? - null : (Vector2D) line.toSpace((Point) new Vector1D(i.getSup())); + null : line.toSpace(new Vector1D(i.getSup())); // recover the connectivity information - final BSPTree startN = selectClosest(startV, splitters); - final BSPTree endN = selectClosest(endV, splitters); + final BSPTree startN = selectClosest(startV, splitters); + final BSPTree endN = selectClosest(endV, splitters); if (reversed) { segments.add(new ConnectableSegment(endV, startV, line.getReverse(), @@ -1076,16 +1076,17 @@ private void addContribution(final SubHyperplane sub, * @param candidates candidate nodes * @return node closest to point, or null if no node is closer than tolerance */ - private BSPTree selectClosest(final Vector2D point, final Iterable> candidates) { + private BSPTree selectClosest(final Vector2D point, + final Iterable> candidates) { if (point == null) { return null; } - BSPTree selected = null; + BSPTree selected = null; double min = Double.POSITIVE_INFINITY; - for (final BSPTree node : candidates) { + for (final BSPTree node : candidates) { final double distance = FastMath.abs(node.getCut().getHyperplane().getOffset(point)); if (distance < min) { selected = node; diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/twod/SubLine.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/twod/SubLine.java index 06c139c6f..97a387daa 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/twod/SubLine.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/twod/SubLine.java @@ -24,7 +24,6 @@ import java.util.ArrayList; import java.util.List; -import org.hipparchus.geometry.Point; import org.hipparchus.geometry.euclidean.oned.Euclidean1D; import org.hipparchus.geometry.euclidean.oned.Interval; import org.hipparchus.geometry.euclidean.oned.IntervalsSet; @@ -40,14 +39,14 @@ /** This class represents a sub-hyperplane for {@link Line}. */ -public class SubLine extends AbstractSubHyperplane { +public class SubLine extends AbstractSubHyperplane { /** Simple constructor. * @param hyperplane underlying hyperplane * @param remainingRegion remaining region of the hyperplane */ - public SubLine(final Hyperplane hyperplane, - final Region remainingRegion) { + public SubLine(final Hyperplane hyperplane, + final Region remainingRegion) { super(hyperplane, remainingRegion); } @@ -89,8 +88,8 @@ public List getSegments() { final List segments = new ArrayList<>(list.size()); for (final Interval interval : list) { - final Vector2D start = line.toSpace((Point) new Vector1D(interval.getInf())); - final Vector2D end = line.toSpace((Point) new Vector1D(interval.getSup())); + final Vector2D start = line.toSpace(new Vector1D(interval.getInf())); + final Vector2D end = line.toSpace(new Vector1D(interval.getSup())); segments.add(new Segment(start, end, line)); } @@ -125,10 +124,10 @@ public Vector2D intersection(final SubLine subLine, final boolean includeEndPoin } // check location of point with respect to first sub-line - Location loc1 = getRemainingRegion().checkPoint(line1.toSubSpace((Point) v2D)); + Location loc1 = getRemainingRegion().checkPoint(line1.toSubSpace(v2D)); // check location of point with respect to second sub-line - Location loc2 = subLine.getRemainingRegion().checkPoint(line2.toSubSpace((Point) v2D)); + Location loc2 = subLine.getRemainingRegion().checkPoint(line2.toSubSpace(v2D)); if (includeEndPoints) { return ((loc1 != Location.OUTSIDE) && (loc2 != Location.OUTSIDE)) ? v2D : null; @@ -146,21 +145,22 @@ public Vector2D intersection(final SubLine subLine, final boolean includeEndPoin */ private static IntervalsSet buildIntervalSet(final Vector2D start, final Vector2D end, final double tolerance) { final Line line = new Line(start, end, tolerance); - return new IntervalsSet(line.toSubSpace((Point) start).getX(), - line.toSubSpace((Point) end).getX(), + return new IntervalsSet(line.toSubSpace(start).getX(), + line.toSubSpace(end).getX(), tolerance); } /** {@inheritDoc} */ @Override - protected AbstractSubHyperplane buildNew(final Hyperplane hyperplane, - final Region remainingRegion) { + protected AbstractSubHyperplane + buildNew(final Hyperplane hyperplane, + final Region remainingRegion) { return new SubLine(hyperplane, remainingRegion); } /** {@inheritDoc} */ @Override - public SplitSubHyperplane split(final Hyperplane hyperplane) { + public SplitSubHyperplane split(final Hyperplane hyperplane) { final Line thisLine = (Line) getHyperplane(); final Line otherLine = (Line) hyperplane; @@ -171,31 +171,31 @@ public SplitSubHyperplane split(final Hyperplane hyper // the lines are parallel final double global = otherLine.getOffset(thisLine); if (global < -tolerance) { - return new SplitSubHyperplane(null, this); + return new SplitSubHyperplane<>(null, this); } else if (global > tolerance) { - return new SplitSubHyperplane(this, null); + return new SplitSubHyperplane<>(this, null); } else { - return new SplitSubHyperplane(null, null); + return new SplitSubHyperplane<>(null, null); } } // the lines do intersect final boolean direct = FastMath.sin(thisLine.getAngle() - otherLine.getAngle()) < 0; - final Vector1D x = thisLine.toSubSpace((Point) crossing); - final SubHyperplane subPlus = + final Vector1D x = thisLine.toSubSpace(crossing); + final SubHyperplane subPlus = new OrientedPoint(x, !direct, tolerance).wholeHyperplane(); - final SubHyperplane subMinus = + final SubHyperplane subMinus = new OrientedPoint(x, direct, tolerance).wholeHyperplane(); - final BSPTree splitTree = getRemainingRegion().getTree(false).split(subMinus); - final BSPTree plusTree = getRemainingRegion().isEmpty(splitTree.getPlus()) ? - new BSPTree<>(Boolean.FALSE) : - new BSPTree<>(subPlus, new BSPTree<>(Boolean.FALSE), - splitTree.getPlus(), null); - final BSPTree minusTree = getRemainingRegion().isEmpty(splitTree.getMinus()) ? - new BSPTree<>(Boolean.FALSE) : - new BSPTree<>(subMinus, new BSPTree<>(Boolean.FALSE), - splitTree.getMinus(), null); + final BSPTree splitTree = getRemainingRegion().getTree(false).split(subMinus); + final BSPTree plusTree = getRemainingRegion().isEmpty(splitTree.getPlus()) ? + new BSPTree<>(Boolean.FALSE) : + new BSPTree<>(subPlus, new BSPTree<>(Boolean.FALSE), + splitTree.getPlus(), null); + final BSPTree minusTree = getRemainingRegion().isEmpty(splitTree.getMinus()) ? + new BSPTree<>(Boolean.FALSE) : + new BSPTree<>(subMinus, new BSPTree<>(Boolean.FALSE), + splitTree.getMinus(), null); return new SplitSubHyperplane<>(new SubLine(thisLine.copySelf(), new IntervalsSet(plusTree, tolerance)), new SubLine(thisLine.copySelf(), new IntervalsSet(minusTree, tolerance))); diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/twod/hull/ConvexHull2D.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/twod/hull/ConvexHull2D.java index 33b422742..1cb2c71f5 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/twod/hull/ConvexHull2D.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/euclidean/twod/hull/ConvexHull2D.java @@ -158,11 +158,11 @@ private Segment[] retrieveLineSegments() { /** {@inheritDoc} */ @Override - public Region createRegion() throws MathIllegalArgumentException { + public Region createRegion() throws MathIllegalArgumentException { if (vertices.length < 3) { throw new MathIllegalArgumentException(LocalizedCoreFormats.INSUFFICIENT_DATA); } - final RegionFactory factory = new RegionFactory<>(); + final RegionFactory factory = new RegionFactory<>(); final Segment[] segments = retrieveLineSegments(); final Line[] lineArray = new Line[segments.length]; for (int i = 0; i < segments.length; i++) { diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/hull/ConvexHull.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/hull/ConvexHull.java index ba08c1045..d96c3271b 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/hull/ConvexHull.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/hull/ConvexHull.java @@ -43,5 +43,5 @@ public interface ConvexHull> extends Seriali * @throws MathIllegalArgumentException if the number of vertices is not enough to * build a region in the respective space */ - Region createRegion() throws MathIllegalArgumentException; + Region createRegion() throws MathIllegalArgumentException; } diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/AbstractRegion.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/AbstractRegion.java index 1a5c01bbe..28a53a8a9 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/AbstractRegion.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/AbstractRegion.java @@ -31,18 +31,20 @@ import org.hipparchus.geometry.Point; import org.hipparchus.geometry.Space; -import org.hipparchus.geometry.Vector; /** Abstract class for all regions, independently of geometry type or dimension. * @param Type of the space. + * @param

Type of the points in the space. * @param Type of the sub-space. + * @param Type of the points in the sub-space. */ -public abstract class AbstractRegion implements Region { +public abstract class AbstractRegion, T extends Space, Q extends Point> + implements Region { /** Inside/Outside BSP tree. */ - private BSPTree tree; + private final BSPTree tree; /** Tolerance below which points are considered to belong to hyperplanes. */ private final double tolerance; @@ -51,7 +53,7 @@ public abstract class AbstractRegion implement private double size; /** Barycenter. */ - private Point barycenter; + private P barycenter; /** Build a region representing the whole space. * @param tolerance tolerance below which points are considered identical. @@ -74,7 +76,7 @@ protected AbstractRegion(final double tolerance) { * @param tree inside/outside BSP tree representing the region * @param tolerance tolerance below which points are considered identical. */ - protected AbstractRegion(final BSPTree tree, final double tolerance) { + protected AbstractRegion(final BSPTree tree, final double tolerance) { this.tree = tree; this.tolerance = tolerance; } @@ -99,7 +101,7 @@ protected AbstractRegion(final BSPTree tree, final double tolerance) { * collection of {@link SubHyperplane SubHyperplane} objects * @param tolerance tolerance below which points are considered identical. */ - protected AbstractRegion(final Collection> boundary, final double tolerance) { + protected AbstractRegion(final Collection> boundary, final double tolerance) { this.tolerance = tolerance; @@ -113,10 +115,10 @@ protected AbstractRegion(final Collection> boundary, final doub // sort the boundary elements in decreasing size order // (we don't want equal size elements to be removed, so // we use a trick to fool the TreeSet) - final TreeSet> ordered = new TreeSet<>(new Comparator>() { + final TreeSet> ordered = new TreeSet<>(new Comparator>() { /** {@inheritDoc} */ @Override - public int compare(final SubHyperplane o1, final SubHyperplane o2) { + public int compare(final SubHyperplane o1, final SubHyperplane o2) { final double size1 = o1.getSize(); final double size2 = o2.getSize(); return (size2 < size1) ? -1 : ((o1 == o2) ? 0 : +1); @@ -129,22 +131,22 @@ public int compare(final SubHyperplane o1, final SubHyperplane o2) { insertCuts(tree, ordered); // set up the inside/outside flags - tree.visit(new BSPTreeVisitor() { + tree.visit(new BSPTreeVisitor() { /** {@inheritDoc} */ @Override - public Order visitOrder(final BSPTree node) { + public Order visitOrder(final BSPTree node) { return Order.PLUS_SUB_MINUS; } /** {@inheritDoc} */ @Override - public void visitInternalNode(final BSPTree node) { + public void visitInternalNode(final BSPTree node) { } /** {@inheritDoc} */ @Override - public void visitLeafNode(final BSPTree node) { + public void visitLeafNode(final BSPTree node) { if (node.getParent() == null || node == node.getParent().getMinus()) { node.setAttribute(Boolean.TRUE); } else { @@ -162,7 +164,7 @@ public void visitLeafNode(final BSPTree node) { * empty region will be built) * @param tolerance tolerance below which points are considered identical. */ - public AbstractRegion(final Hyperplane[] hyperplanes, final double tolerance) { + public AbstractRegion(final Hyperplane[] hyperplanes, final double tolerance) { this.tolerance = tolerance; if ((hyperplanes == null) || (hyperplanes.length == 0)) { tree = new BSPTree<>(Boolean.FALSE); @@ -172,9 +174,9 @@ public AbstractRegion(final Hyperplane[] hyperplanes, final double tolerance) tree = hyperplanes[0].wholeSpace().getTree(false); // chop off parts of the space - BSPTree node = tree; + BSPTree node = tree; node.setAttribute(Boolean.TRUE); - for (final Hyperplane hyperplane : hyperplanes) { + for (final Hyperplane hyperplane : hyperplanes) { if (node.insertCut(hyperplane)) { node.setAttribute(null); node.getPlus().setAttribute(Boolean.FALSE); @@ -189,7 +191,7 @@ public AbstractRegion(final Hyperplane[] hyperplanes, final double tolerance) /** {@inheritDoc} */ @Override - public abstract AbstractRegion buildNew(BSPTree newTree); + public abstract AbstractRegion buildNew(BSPTree newTree); /** Get the tolerance below which points are considered to belong to hyperplanes. * @return tolerance below which points are considered to belong to hyperplanes @@ -204,12 +206,12 @@ public double getTolerance() { * @param boundary collection of edges belonging to the cell defined * by the node */ - private void insertCuts(final BSPTree node, final Collection> boundary) { + private void insertCuts(final BSPTree node, final Collection> boundary) { - final Iterator> iterator = boundary.iterator(); + final Iterator> iterator = boundary.iterator(); // build the current level - Hyperplane inserted = null; + Hyperplane inserted = null; while ((inserted == null) && iterator.hasNext()) { inserted = iterator.next().getHyperplane(); if (!node.insertCut(inserted.copySelf())) { @@ -222,11 +224,11 @@ private void insertCuts(final BSPTree node, final Collection } // distribute the remaining edges in the two sub-trees - final ArrayList> plusList = new ArrayList<>(); - final ArrayList> minusList = new ArrayList<>(); + final ArrayList> plusList = new ArrayList<>(); + final ArrayList> minusList = new ArrayList<>(); while (iterator.hasNext()) { - final SubHyperplane other = iterator.next(); - final SubHyperplane.SplitSubHyperplane split = other.split(inserted); + final SubHyperplane other = iterator.next(); + final SubHyperplane.SplitSubHyperplane split = other.split(inserted); switch (split.getSide()) { case PLUS: plusList.add(other); @@ -251,7 +253,7 @@ private void insertCuts(final BSPTree node, final Collection /** {@inheritDoc} */ @Override - public AbstractRegion copySelf() { + public AbstractRegion copySelf() { return buildNew(tree.copySelf()); } @@ -263,7 +265,7 @@ public boolean isEmpty() { /** {@inheritDoc} */ @Override - public boolean isEmpty(final BSPTree node) { + public boolean isEmpty(final BSPTree node) { // we use a recursive function rather than the BSPTreeVisitor // interface because we can stop visiting the tree as soon as we @@ -287,7 +289,7 @@ public boolean isFull() { /** {@inheritDoc} */ @Override - public boolean isFull(final BSPTree node) { + public boolean isFull(final BSPTree node) { // we use a recursive function rather than the BSPTreeVisitor // interface because we can stop visiting the tree as soon as we @@ -305,57 +307,34 @@ public boolean isFull(final BSPTree node) { /** {@inheritDoc} */ @Override - public boolean contains(final Region region) { - return new RegionFactory().difference(region, this).isEmpty(); + public boolean contains(final Region region) { + return new RegionFactory().difference(region, this).isEmpty(); } /** {@inheritDoc} */ @Override - public BoundaryProjection projectToBoundary(final Point point) { - final BoundaryProjector projector = new BoundaryProjector<>(point); + public BoundaryProjection projectToBoundary(final P point) { + final BoundaryProjector projector = new BoundaryProjector<>(point); getTree(true).visit(projector); return projector.getProjection(); } - /** Check a point with respect to the region. - * @param point point to check - * @param type of vector implementing Vector interface - * @return a code representing the point status: either {@link - * Region.Location#INSIDE}, {@link Region.Location#OUTSIDE} or - * {@link Region.Location#BOUNDARY} - */ - public > Location checkPoint(final Vector point) { - return checkPoint((Point) point); - } - /** {@inheritDoc} */ @Override - public Location checkPoint(final Point point) { + public Location checkPoint(final P point) { return checkPoint(tree, point); } /** Check a point with respect to the region starting at a given node. * @param node root node of the region * @param point point to check - * @param type of vector implementing Vector interface * @return a code representing the point status: either {@link * Region.Location#INSIDE INSIDE}, {@link Region.Location#OUTSIDE * OUTSIDE} or {@link Region.Location#BOUNDARY BOUNDARY} */ - protected > Location checkPoint(final BSPTree node, final Vector point) { - return checkPoint(node, (Point) point); - } - - /** Check a point with respect to the region starting at a given node. - * @param node root node of the region - * @param point point to check - * @return a code representing the point status: either {@link - * Region.Location#INSIDE INSIDE}, {@link Region.Location#OUTSIDE - * OUTSIDE} or {@link Region.Location#BOUNDARY BOUNDARY} - */ - protected Location checkPoint(final BSPTree node, final Point point) { - final BSPTree cell = node.getCell(point, tolerance); + protected Location checkPoint(final BSPTree node, final P point) { + final BSPTree cell = node.getCell(point, tolerance); if (cell.getCut() == null) { // the point is in the interior of a cell, just check the attribute return ((Boolean) cell.getAttribute()) ? Location.INSIDE : Location.OUTSIDE; @@ -370,10 +349,10 @@ protected Location checkPoint(final BSPTree node, final Point point) { /** {@inheritDoc} */ @Override - public BSPTree getTree(final boolean includeBoundaryAttributes) { + public BSPTree getTree(final boolean includeBoundaryAttributes) { if (includeBoundaryAttributes && (tree.getCut() != null) && (tree.getAttribute() == null)) { // compute the boundary attributes - tree.visit(new BoundaryBuilder()); + tree.visit(new BoundaryBuilder<>()); } return tree; } @@ -381,7 +360,7 @@ public BSPTree getTree(final boolean includeBoundaryAttributes) { /** {@inheritDoc} */ @Override public double getBoundarySize() { - final BoundarySizeVisitor visitor = new BoundarySizeVisitor<>(); + final BoundarySizeVisitor visitor = new BoundarySizeVisitor<>(); getTree(true).visit(visitor); return visitor.getSize(); } @@ -404,25 +383,17 @@ protected void setSize(final double size) { /** {@inheritDoc} */ @Override - public Point getBarycenter() { + public P getBarycenter() { if (barycenter == null) { computeGeometricalProperties(); } return barycenter; } - /** Set the barycenter of the instance. - * @param barycenter barycenter of the instance - * @param type of vector implementing Vector interface - */ - protected > void setBarycenter(final Vector barycenter) { - setBarycenter((Point) barycenter); - } - /** Set the barycenter of the instance. * @param barycenter barycenter of the instance */ - protected void setBarycenter(final Point barycenter) { + protected void setBarycenter(final P barycenter) { this.barycenter = barycenter; } @@ -433,7 +404,7 @@ protected void setBarycenter(final Point barycenter) { /** {@inheritDoc} */ @Override - public SubHyperplane intersection(final SubHyperplane sub) { + public SubHyperplane intersection(final SubHyperplane sub) { return recurseIntersection(tree, sub); } @@ -443,19 +414,19 @@ public SubHyperplane intersection(final SubHyperplane sub) { * @param sub sub-hyperplane traversing the region * @return filtered sub-hyperplane */ - private SubHyperplane recurseIntersection(final BSPTree node, final SubHyperplane sub) { + private SubHyperplane recurseIntersection(final BSPTree node, final SubHyperplane sub) { if (node.getCut() == null) { return (Boolean) node.getAttribute() ? sub.copySelf() : null; } - final Hyperplane hyperplane = node.getCut().getHyperplane(); - final SubHyperplane.SplitSubHyperplane split = sub.split(hyperplane); + final Hyperplane hyperplane = node.getCut().getHyperplane(); + final SubHyperplane.SplitSubHyperplane split = sub.split(hyperplane); if (split.getPlus() != null) { if (split.getMinus() != null) { // both sides - final SubHyperplane plus = recurseIntersection(node.getPlus(), split.getPlus()); - final SubHyperplane minus = recurseIntersection(node.getMinus(), split.getMinus()); + final SubHyperplane plus = recurseIntersection(node.getPlus(), split.getPlus()); + final SubHyperplane minus = recurseIntersection(node.getMinus(), split.getMinus()); if (plus == null) { return minus; } else if (minus == null) { @@ -488,21 +459,21 @@ private SubHyperplane recurseIntersection(final BSPTree node, final SubHyp * @return a new region, resulting from the application of the * transform to the instance */ - public AbstractRegion applyTransform(final Transform transform) { + public AbstractRegion applyTransform(final Transform transform) { // transform the tree, except for boundary attribute splitters - final Map, BSPTree> map = new HashMap<>(); - final BSPTree transformedTree = recurseTransform(getTree(false), transform, map); + final Map, BSPTree> map = new HashMap<>(); + final BSPTree transformedTree = recurseTransform(getTree(false), transform, map); // set up the boundary attributes splitters - for (final Map.Entry, BSPTree> entry : map.entrySet()) { + for (final Map.Entry, BSPTree> entry : map.entrySet()) { if (entry.getKey().getCut() != null) { @SuppressWarnings("unchecked") - BoundaryAttribute original = (BoundaryAttribute) entry.getKey().getAttribute(); + BoundaryAttribute original = (BoundaryAttribute) entry.getKey().getAttribute(); if (original != null) { @SuppressWarnings("unchecked") - BoundaryAttribute transformed = (BoundaryAttribute) entry.getValue().getAttribute(); - for (final BSPTree splitter : original.getSplitters()) { + BoundaryAttribute transformed = (BoundaryAttribute) entry.getValue().getAttribute(); + for (final BSPTree splitter : original.getSplitters()) { transformed.getSplitters().add(map.get(splitter)); } } @@ -520,22 +491,22 @@ public AbstractRegion applyTransform(final Transform transform) { * @return a new tree */ @SuppressWarnings("unchecked") - private BSPTree recurseTransform(final BSPTree node, final Transform transform, - final Map, BSPTree> map) { + private BSPTree recurseTransform(final BSPTree node, final Transform transform, + final Map, BSPTree> map) { - final BSPTree transformedNode; + final BSPTree transformedNode; if (node.getCut() == null) { transformedNode = new BSPTree<>(node.getAttribute()); } else { - final SubHyperplane sub = node.getCut(); - final SubHyperplane tSub = ((AbstractSubHyperplane) sub).applyTransform(transform); - BoundaryAttribute attribute = (BoundaryAttribute) node.getAttribute(); + final SubHyperplane sub = node.getCut(); + final SubHyperplane tSub = ((AbstractSubHyperplane) sub).applyTransform(transform); + BoundaryAttribute attribute = (BoundaryAttribute) node.getAttribute(); if (attribute != null) { - final SubHyperplane tPO = (attribute.getPlusOutside() == null) ? - null : ((AbstractSubHyperplane) attribute.getPlusOutside()).applyTransform(transform); - final SubHyperplane tPI = (attribute.getPlusInside() == null) ? - null : ((AbstractSubHyperplane) attribute.getPlusInside()).applyTransform(transform); + final SubHyperplane tPO = (attribute.getPlusOutside() == null) ? + null : ((AbstractSubHyperplane) attribute.getPlusOutside()).applyTransform(transform); + final SubHyperplane tPI = (attribute.getPlusInside() == null) ? + null : ((AbstractSubHyperplane) attribute.getPlusInside()).applyTransform(transform); // we start with an empty list of splitters, it will be filled in out of recursion attribute = new BoundaryAttribute<>(tPO, tPI, new NodesSet<>()); } diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/AbstractSubHyperplane.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/AbstractSubHyperplane.java index 57125009a..a2b3045f9 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/AbstractSubHyperplane.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/AbstractSubHyperplane.java @@ -24,6 +24,7 @@ import java.util.HashMap; import java.util.Map; +import org.hipparchus.geometry.Point; import org.hipparchus.geometry.Space; /** This class implements the dimension-independent parts of {@link SubHyperplane}. @@ -35,25 +36,27 @@ * hyperplane with the convex region which it splits, the chopping * hyperplanes are the cut hyperplanes closer to the tree root.

- * @param Type of the embedding space. - * @param Type of the embedded sub-space. + * @param Type of the space. + * @param

Type of the points in space. + * @param Type of the sub-space. + * @param Type of the points in sub-space. */ -public abstract class AbstractSubHyperplane - implements SubHyperplane { +public abstract class AbstractSubHyperplane, T extends Space, Q extends Point> + implements SubHyperplane { /** Underlying hyperplane. */ - private final Hyperplane hyperplane; + private final Hyperplane hyperplane; /** Remaining region of the hyperplane. */ - private final Region remainingRegion; + private final Region remainingRegion; /** Build a sub-hyperplane from an hyperplane and a region. * @param hyperplane underlying hyperplane * @param remainingRegion remaining region of the hyperplane */ - protected AbstractSubHyperplane(final Hyperplane hyperplane, - final Region remainingRegion) { + protected AbstractSubHyperplane(final Hyperplane hyperplane, + final Region remainingRegion) { this.hyperplane = hyperplane; this.remainingRegion = remainingRegion; } @@ -63,12 +66,12 @@ protected AbstractSubHyperplane(final Hyperplane hyperplane, * @param remaining remaining region of the hyperplane * @return a new sub-hyperplane */ - protected abstract AbstractSubHyperplane buildNew(Hyperplane hyper, - Region remaining); + protected abstract AbstractSubHyperplane buildNew(Hyperplane hyper, + Region remaining); /** {@inheritDoc} */ @Override - public AbstractSubHyperplane copySelf() { + public AbstractSubHyperplane copySelf() { return buildNew(hyperplane.copySelf(), remainingRegion); } @@ -76,7 +79,7 @@ public AbstractSubHyperplane copySelf() { * @return underlying hyperplane */ @Override - public Hyperplane getHyperplane() { + public Hyperplane getHyperplane() { return hyperplane; } @@ -87,7 +90,7 @@ public Hyperplane getHyperplane() { * corresponding region is a convex 2D polygon.

* @return remaining region of the hyperplane */ - public Region getRemainingRegion() { + public Region getRemainingRegion() { return remainingRegion; } @@ -99,11 +102,10 @@ public double getSize() { /** {@inheritDoc} */ @Override - public AbstractSubHyperplane reunite(final SubHyperplane other) { - @SuppressWarnings("unchecked") - AbstractSubHyperplane o = (AbstractSubHyperplane) other; + public AbstractSubHyperplane reunite(final SubHyperplane other) { + AbstractSubHyperplane o = (AbstractSubHyperplane) other; return buildNew(hyperplane, - new RegionFactory().union(remainingRegion, o.remainingRegion)); + new RegionFactory().union(remainingRegion, o.remainingRegion)); } /** Apply a transform to the instance. @@ -116,23 +118,23 @@ public AbstractSubHyperplane reunite(final SubHyperplane other) { * @param transform D-dimension transform to apply * @return the transformed instance */ - public AbstractSubHyperplane applyTransform(final Transform transform) { - final Hyperplane tHyperplane = transform.apply(hyperplane); + public AbstractSubHyperplane applyTransform(final Transform transform) { + final Hyperplane tHyperplane = transform.apply(hyperplane); // transform the tree, except for boundary attribute splitters - final Map, BSPTree> map = new HashMap<>(); - final BSPTree tTree = + final Map, BSPTree> map = new HashMap<>(); + final BSPTree tTree = recurseTransform(remainingRegion.getTree(false), tHyperplane, transform, map); // set up the boundary attributes splitters - for (final Map.Entry, BSPTree> entry : map.entrySet()) { + for (final Map.Entry, BSPTree> entry : map.entrySet()) { if (entry.getKey().getCut() != null) { @SuppressWarnings("unchecked") - BoundaryAttribute original = (BoundaryAttribute) entry.getKey().getAttribute(); + BoundaryAttribute original = (BoundaryAttribute) entry.getKey().getAttribute(); if (original != null) { @SuppressWarnings("unchecked") - BoundaryAttribute transformed = (BoundaryAttribute) entry.getValue().getAttribute(); - for (final BSPTree splitter : original.getSplitters()) { + BoundaryAttribute transformed = (BoundaryAttribute) entry.getValue().getAttribute(); + for (final BSPTree splitter : original.getSplitters()) { transformed.getSplitters().add(map.get(splitter)); } } @@ -150,22 +152,22 @@ public AbstractSubHyperplane applyTransform(final Transform transfor * @param map transformed nodes map * @return a new tree */ - private BSPTree recurseTransform(final BSPTree node, - final Hyperplane transformed, - final Transform transform, - final Map, BSPTree> map) { + private BSPTree recurseTransform(final BSPTree node, + final Hyperplane transformed, + final Transform transform, + final Map, BSPTree> map) { - final BSPTree transformedNode; + final BSPTree transformedNode; if (node.getCut() == null) { transformedNode = new BSPTree<>(node.getAttribute()); } else { @SuppressWarnings("unchecked") - BoundaryAttribute attribute = (BoundaryAttribute) node.getAttribute(); + BoundaryAttribute attribute = (BoundaryAttribute) node.getAttribute(); if (attribute != null) { - final SubHyperplane tPO = (attribute.getPlusOutside() == null) ? + final SubHyperplane tPO = (attribute.getPlusOutside() == null) ? null : transform.apply(attribute.getPlusOutside(), hyperplane, transformed); - final SubHyperplane tPI = (attribute.getPlusInside() == null) ? + final SubHyperplane tPI = (attribute.getPlusInside() == null) ? null : transform.apply(attribute.getPlusInside(), hyperplane, transformed); // we start with an empty list of splitters, it will be filled in out of recursion attribute = new BoundaryAttribute<>(tPO, tPI, new NodesSet<>()); @@ -184,7 +186,7 @@ private BSPTree recurseTransform(final BSPTree node, /** {@inheritDoc} */ @Override - public abstract SplitSubHyperplane split(Hyperplane hyper); + public abstract SplitSubHyperplane split(Hyperplane hyper); /** {@inheritDoc} */ @Override diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/BSPTree.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/BSPTree.java index f4703e09b..fd4ed7c12 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/BSPTree.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/BSPTree.java @@ -64,21 +64,22 @@ * Association for Computing Machinery (ACM).

* @param Type of the space. + * @param

Type of the points in space. */ -public class BSPTree { +public class BSPTree> { /** Cut sub-hyperplane. */ - private SubHyperplane cut; + private SubHyperplane cut; /** Tree at the plus side of the cut hyperplane. */ - private BSPTree plus; + private BSPTree plus; /** Tree at the minus side of the cut hyperplane. */ - private BSPTree minus; + private BSPTree minus; /** Parent tree. */ - private BSPTree parent; + private BSPTree parent; /** Application-defined attribute. */ private Object attribute; @@ -117,7 +118,7 @@ public BSPTree(final Object attribute) { * @param attribute attribute associated with the node (may be null) * @see #insertCut */ - public BSPTree(final SubHyperplane cut, final BSPTree plus, final BSPTree minus, + public BSPTree(final SubHyperplane cut, final BSPTree plus, final BSPTree minus, final Object attribute) { this.cut = cut; this.plus = plus; @@ -151,14 +152,14 @@ public BSPTree(final SubHyperplane cut, final BSPTree plus, final BSPTree< * the cell now has two leaf child nodes) * @see #BSPTree(SubHyperplane, BSPTree, BSPTree, Object) */ - public boolean insertCut(final Hyperplane hyperplane) { + public boolean insertCut(final Hyperplane hyperplane) { if (cut != null) { plus.parent = null; minus.parent = null; } - final SubHyperplane chopped = fitToCell(hyperplane.wholeHyperplane()); + final SubHyperplane chopped = fitToCell(hyperplane.wholeHyperplane()); if (chopped == null || chopped.isEmpty()) { cut = null; plus = null; @@ -182,21 +183,20 @@ public boolean insertCut(final Hyperplane hyperplane) { * objects).

* @return a new tree, copy of the instance */ - public BSPTree copySelf() { + public BSPTree copySelf() { if (cut == null) { - return new BSPTree(attribute); + return new BSPTree<>(attribute); } - return new BSPTree(cut.copySelf(), plus.copySelf(), minus.copySelf(), - attribute); + return new BSPTree<>(cut.copySelf(), plus.copySelf(), minus.copySelf(), attribute); } /** Get the cut sub-hyperplane. * @return cut sub-hyperplane, null if this is a leaf tree */ - public SubHyperplane getCut() { + public SubHyperplane getCut() { return cut; } @@ -204,7 +204,7 @@ public SubHyperplane getCut() { * @return tree on the plus side of the cut hyperplane, null if this * is a leaf tree */ - public BSPTree getPlus() { + public BSPTree getPlus() { return plus; } @@ -212,14 +212,14 @@ public BSPTree getPlus() { * @return tree on the minus side of the cut hyperplane, null if this * is a leaf tree */ - public BSPTree getMinus() { + public BSPTree getMinus() { return minus; } /** Get the parent node. * @return parent node, null if the node has no parents */ - public BSPTree getParent() { + public BSPTree getParent() { return parent; } @@ -244,7 +244,7 @@ public Object getAttribute() { /** Visit the BSP tree nodes. * @param visitor object visiting the tree nodes */ - public void visit(final BSPTreeVisitor visitor) { + public void visit(final BSPTreeVisitor visitor) { if (cut == null) { visitor.visitLeafNode(this); } else { @@ -294,9 +294,9 @@ public void visit(final BSPTreeVisitor visitor) { * @return a new sub-hyperplane, guaranteed to have no part outside * of the instance cell */ - private SubHyperplane fitToCell(final SubHyperplane sub) { - SubHyperplane s = sub; - for (BSPTree tree = this; tree.parent != null && s != null; tree = tree.parent) { + private SubHyperplane fitToCell(final SubHyperplane sub) { + SubHyperplane s = sub; + for (BSPTree tree = this; tree.parent != null && s != null; tree = tree.parent) { if (tree == tree.parent.plus) { s = s.split(tree.parent.cut.getHyperplane()).getPlus(); } else { @@ -315,7 +315,7 @@ private SubHyperplane fitToCell(final SubHyperplane sub) { * are considered to belong to the hyperplane itself * @return the tree cell to which the point belongs */ - public BSPTree getCell(final Point point, final double tolerance) { + public BSPTree getCell(final P point, final double tolerance) { if (cut == null) { return this; @@ -343,8 +343,8 @@ public BSPTree getCell(final Point point, final double tolerance) { * @return close cells (may be empty if all cut sub-hyperplanes are farther * than maxOffset from the point) */ - public List> getCloseCuts(final Point point, final double maxOffset) { - final List> close = new ArrayList<>(); + public List> getCloseCuts(final P point, final double maxOffset) { + final List> close = new ArrayList<>(); recurseCloseCuts(point, maxOffset, close); return close; } @@ -355,8 +355,8 @@ public List> getCloseCuts(final Point point, final double maxOffse * close to the point (in absolute value) * @param close list to fill */ - private void recurseCloseCuts(final Point point, final double maxOffset, - final List> close) { + private void recurseCloseCuts(final P point, final double maxOffset, + final List> close) { if (cut != null) { // position of the point with respect to the cut hyperplane @@ -411,7 +411,7 @@ private void condense() { * tree, this value can be ignored if parentTree is not null * since all connections have already been established */ - public BSPTree merge(final BSPTree tree, final LeafMerger leafMerger) { + public BSPTree merge(final BSPTree tree, final LeafMerger leafMerger) { return merge(tree, leafMerger, null, false); } @@ -430,8 +430,8 @@ public BSPTree merge(final BSPTree tree, final LeafMerger leafMerger) { * tree, this value can be ignored if parentTree is not null * since all connections have already been established */ - private BSPTree merge(final BSPTree tree, final LeafMerger leafMerger, - final BSPTree parentTree, final boolean isPlusChild) { + private BSPTree merge(final BSPTree tree, final LeafMerger leafMerger, + final BSPTree parentTree, final boolean isPlusChild) { if (cut == null) { // cell/tree operation return leafMerger.merge(this, tree, parentTree, isPlusChild, true); @@ -440,7 +440,7 @@ private BSPTree merge(final BSPTree tree, final LeafMerger leafMerger, return leafMerger.merge(tree, this, parentTree, isPlusChild, false); } else { // tree/tree operation - final BSPTree merged = tree.split(cut); + final BSPTree merged = tree.split(cut); if (parentTree != null) { merged.parent = parentTree; if (isPlusChild) { @@ -478,8 +478,9 @@ private BSPTree merge(final BSPTree tree, final LeafMerger leafMerger, * merging phase of the four set operations union, intersection, * difference and symmetric difference (exclusive or).

* @param Type of the space. + * @param

Type of the points in space. */ - public interface LeafMerger { + public interface LeafMerger> { /** Merge a leaf node and a tree node. *

This method is called at the end of a recursive merging @@ -510,7 +511,7 @@ public interface LeafMerger { * @return the BSP tree resulting from the merging (may be one of * the arguments) */ - BSPTree merge(BSPTree leaf, BSPTree tree, BSPTree parentTree, + BSPTree merge(BSPTree leaf, BSPTree tree, BSPTree parentTree, boolean isPlusChild, boolean leafFromInstance); } @@ -525,14 +526,15 @@ BSPTree merge(BSPTree leaf, BSPTree tree, BSPTree parentTree, * setting *

* @param Type of the space. + * @param

Type of the points in space. */ - public interface VanishingCutHandler { + public interface VanishingCutHandler> { /** Fix a node with both vanished cut and children. * @param node node to fix * @return fixed node */ - BSPTree fixNode(BSPTree node); + BSPTree fixNode(BSPTree node); } @@ -554,27 +556,25 @@ public interface VanishingCutHandler { * sub-hyperplane, the two parts of the split instance as its two * sub-trees and a null parent */ - public BSPTree split(final SubHyperplane sub) { + public BSPTree split(final SubHyperplane sub) { if (cut == null) { - return new BSPTree(sub, copySelf(), new BSPTree(attribute), null); + return new BSPTree<>(sub, copySelf(), new BSPTree<>(attribute), null); } - final Hyperplane cHyperplane = cut.getHyperplane(); - final Hyperplane sHyperplane = sub.getHyperplane(); - final SubHyperplane.SplitSubHyperplane subParts = sub.split(cHyperplane); + final Hyperplane cHyperplane = cut.getHyperplane(); + final Hyperplane sHyperplane = sub.getHyperplane(); + final SubHyperplane.SplitSubHyperplane subParts = sub.split(cHyperplane); switch (subParts.getSide()) { case PLUS : { // the partitioning sub-hyperplane is entirely in the plus sub-tree - final BSPTree split = plus.split(sub); + final BSPTree split = plus.split(sub); if (cut.split(sHyperplane).getSide() == Side.PLUS) { - split.plus = - new BSPTree<>(cut.copySelf(), split.plus, minus.copySelf(), attribute); + split.plus = new BSPTree<>(cut.copySelf(), split.plus, minus.copySelf(), attribute); split.plus.condense(); split.plus.parent = split; } else { - split.minus = - new BSPTree<>(cut.copySelf(), split.minus, minus.copySelf(), attribute); + split.minus = new BSPTree<>(cut.copySelf(), split.minus, minus.copySelf(), attribute); split.minus.condense(); split.minus.parent = split; } @@ -582,15 +582,13 @@ public BSPTree split(final SubHyperplane sub) { } case MINUS : { // the partitioning sub-hyperplane is entirely in the minus sub-tree - final BSPTree split = minus.split(sub); + final BSPTree split = minus.split(sub); if (cut.split(sHyperplane).getSide() == Side.PLUS) { - split.plus = - new BSPTree<>(cut.copySelf(), plus.copySelf(), split.plus, attribute); + split.plus = new BSPTree<>(cut.copySelf(), plus.copySelf(), split.plus, attribute); split.plus.condense(); split.plus.parent = split; } else { - split.minus = - new BSPTree<>(cut.copySelf(), plus.copySelf(), split.minus, attribute); + split.minus = new BSPTree<>(cut.copySelf(), plus.copySelf(), split.minus, attribute); split.minus.condense(); split.minus.parent = split; } @@ -598,11 +596,12 @@ public BSPTree split(final SubHyperplane sub) { } case BOTH : { - final SubHyperplane.SplitSubHyperplane cutParts = cut.split(sHyperplane); - final BSPTree split = - new BSPTree<>(sub, plus.split(subParts.getPlus()), minus.split(subParts.getMinus()), - null); - final BSPTree tmp = split.plus.minus; + final SubHyperplane.SplitSubHyperplane cutParts = cut.split(sHyperplane); + final BSPTree split = new BSPTree<>(sub, + plus.split(subParts.getPlus()), + minus.split(subParts.getMinus()), + null); + final BSPTree tmp = split.plus.minus; split.plus.minus = split.minus.plus; split.plus.minus.parent = split.plus; split.minus.plus = tmp; @@ -641,8 +640,8 @@ public BSPTree split(final SubHyperplane sub) { * cases of vanishing cut sub-hyperplanes in internal nodes during merging * @see LeafMerger */ - public void insertInTree(final BSPTree parentTree, final boolean isPlusChild, - final VanishingCutHandler vanishingHandler) { + public void insertInTree(final BSPTree parentTree, final boolean isPlusChild, + final VanishingCutHandler vanishingHandler) { // set up parent/child links parent = parentTree; @@ -658,35 +657,30 @@ public void insertInTree(final BSPTree parentTree, final boolean isPlusChild, if (cut != null) { // explore the parent nodes from here towards tree root - for (BSPTree tree = this; tree.parent != null; tree = tree.parent) { + for (BSPTree tree = this; tree.parent != null; tree = tree.parent) { // this is an hyperplane of some parent node - final Hyperplane hyperplane = tree.parent.cut.getHyperplane(); + final Hyperplane hyperplane = tree.parent.cut.getHyperplane(); // chop off the parts of the inserted tree that extend // on the wrong side of this parent hyperplane if (tree == tree.parent.plus) { cut = cut.split(hyperplane).getPlus(); + fixVanishingCut(vanishingHandler); + if (cut == null) { + break; + } plus.chopOffMinus(hyperplane, vanishingHandler); minus.chopOffMinus(hyperplane, vanishingHandler); } else { cut = cut.split(hyperplane).getMinus(); - plus.chopOffPlus(hyperplane, vanishingHandler); - minus.chopOffPlus(hyperplane, vanishingHandler); - } - - if (cut == null) { - // the cut sub-hyperplane has vanished - final BSPTree fixed = vanishingHandler.fixNode(this); - cut = fixed.cut; - plus = fixed.plus; - minus = fixed.minus; - attribute = fixed.attribute; + fixVanishingCut(vanishingHandler); if (cut == null) { break; } + plus.chopOffPlus(hyperplane, vanishingHandler); + minus.chopOffPlus(hyperplane, vanishingHandler); } - } // since we may have drop some parts of the inserted tree, @@ -715,17 +709,17 @@ public void insertInTree(final BSPTree parentTree, final boolean isPlusChild, * a single branch with the cell as a leaf node, and other leaf nodes * as the remnants of the pruned branches */ - public BSPTree pruneAroundConvexCell(final Object cellAttribute, + public BSPTree pruneAroundConvexCell(final Object cellAttribute, final Object otherLeafsAttributes, final Object internalAttributes) { // build the current cell leaf - BSPTree tree = new BSPTree<>(cellAttribute); + BSPTree tree = new BSPTree<>(cellAttribute); // build the pruned tree bottom-up - for (BSPTree current = this; current.parent != null; current = current.parent) { - final SubHyperplane parentCut = current.parent.cut.copySelf(); - final BSPTree sibling = new BSPTree<>(otherLeafsAttributes); + for (BSPTree current = this; current.parent != null; current = current.parent) { + final SubHyperplane parentCut = current.parent.cut.copySelf(); + final BSPTree sibling = new BSPTree<>(otherLeafsAttributes); if (current == current.parent.plus) { tree = new BSPTree<>(parentCut, tree, sibling, internalAttributes); } else { @@ -745,21 +739,14 @@ public BSPTree pruneAroundConvexCell(final Object cellAttribute, * @param vanishingHandler handler to use for handling very rare corner * cases of vanishing cut sub-hyperplanes in internal nodes during merging */ - private void chopOffMinus(final Hyperplane hyperplane, final VanishingCutHandler vanishingHandler) { + private void chopOffMinus(final Hyperplane hyperplane, final VanishingCutHandler vanishingHandler) { if (cut != null) { cut = cut.split(hyperplane).getPlus(); plus.chopOffMinus(hyperplane, vanishingHandler); minus.chopOffMinus(hyperplane, vanishingHandler); - if (cut == null) { - // the cut sub-hyperplane has vanished - final BSPTree fixed = vanishingHandler.fixNode(this); - cut = fixed.cut; - plus = fixed.plus; - minus = fixed.minus; - attribute = fixed.attribute; - } + fixVanishingCut(vanishingHandler); } } @@ -772,23 +759,30 @@ private void chopOffMinus(final Hyperplane hyperplane, final VanishingCutHand * @param vanishingHandler handler to use for handling very rare corner * cases of vanishing cut sub-hyperplanes in internal nodes during merging */ - private void chopOffPlus(final Hyperplane hyperplane, final VanishingCutHandler vanishingHandler) { + private void chopOffPlus(final Hyperplane hyperplane, final VanishingCutHandler vanishingHandler) { if (cut != null) { cut = cut.split(hyperplane).getMinus(); plus.chopOffPlus(hyperplane, vanishingHandler); minus.chopOffPlus(hyperplane, vanishingHandler); - if (cut == null) { - // the cut sub-hyperplane has vanished - final BSPTree fixed = vanishingHandler.fixNode(this); - cut = fixed.cut; - plus = fixed.plus; - minus = fixed.minus; - attribute = fixed.attribute; - } + fixVanishingCut(vanishingHandler); } } + /** Fix vanishing cut. + * @param vanishingHandler handler to use for handling very rare corner + */ + private void fixVanishingCut(final VanishingCutHandler vanishingHandler) { + if (cut == null) { + // the cut sub-hyperplane has vanished + final BSPTree fixed = vanishingHandler.fixNode(this); + cut = fixed.cut; + plus = fixed.plus; + minus = fixed.minus; + attribute = fixed.attribute; + } + } + } diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/BSPTreeVisitor.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/BSPTreeVisitor.java index 291bae85c..30d971d96 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/BSPTreeVisitor.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/BSPTreeVisitor.java @@ -21,6 +21,7 @@ */ package org.hipparchus.geometry.partitioning; +import org.hipparchus.geometry.Point; import org.hipparchus.geometry.Space; /** This interface is used to visit {@link BSPTree BSP tree} nodes. @@ -46,12 +47,13 @@ * * @param Type of the space. + * @param

Type of the points in space. * @see BSPTree * @see SubHyperplane */ -public interface BSPTreeVisitor { +public interface BSPTreeVisitor> { /** Enumerate for visit order with respect to plus sub-tree, minus sub-tree and cut sub-hyperplane. */ enum Order { @@ -83,7 +85,7 @@ enum Order { /** Indicator for visit order cut sub-hyperplane, then minus sub-tree, * and last plus sub-tree. */ - SUB_MINUS_PLUS; + SUB_MINUS_PLUS } /** Determine the visit order for this node. @@ -92,27 +94,27 @@ enum Order { * guaranteed that this method will be called before {@link * #visitInternalNode visitInternalNode} for a given node, it will be * called exactly once for each internal node.

- * @param node BSP node guaranteed to have a non null cut sub-hyperplane + * @param node BSP node guaranteed to have a non-null cut sub-hyperplane * @return desired visit order, must be one of * {@link Order#PLUS_MINUS_SUB}, {@link Order#PLUS_SUB_MINUS}, * {@link Order#MINUS_PLUS_SUB}, {@link Order#MINUS_SUB_PLUS}, * {@link Order#SUB_PLUS_MINUS}, {@link Order#SUB_MINUS_PLUS} */ - Order visitOrder(BSPTree node); + Order visitOrder(BSPTree node); - /** Visit a BSP tree node node having a non-null sub-hyperplane. + /** Visit a BSP tree node having a non-null sub-hyperplane. *

It is guaranteed that this method will be called after {@link * #visitOrder visitOrder} has been called for a given node, * it wil be called exactly once for each internal node.

- * @param node BSP node guaranteed to have a non null cut sub-hyperplane + * @param node BSP node guaranteed to have a non-null cut sub-hyperplane * @see #visitLeafNode */ - void visitInternalNode(BSPTree node); + void visitInternalNode(BSPTree node); /** Visit a leaf BSP tree node node having a null sub-hyperplane. * @param node leaf BSP node having a null sub-hyperplane * @see #visitInternalNode */ - void visitLeafNode(BSPTree node); + void visitLeafNode(BSPTree node); } diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/BoundaryAttribute.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/BoundaryAttribute.java index f2b43b152..8f978a873 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/BoundaryAttribute.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/BoundaryAttribute.java @@ -21,6 +21,7 @@ */ package org.hipparchus.geometry.partitioning; +import org.hipparchus.geometry.Point; import org.hipparchus.geometry.Space; /** Class holding boundary attributes. @@ -33,24 +34,25 @@ *

This class is a simple placeholder, it does not provide any * processing methods.

* @param Type of the space. + * @param

Type of the points in space. * @see Region#getTree */ -public class BoundaryAttribute { +public class BoundaryAttribute> { /** Part of the node cut sub-hyperplane that belongs to the * boundary and has the outside of the region on the plus side of * its underlying hyperplane (may be null). */ - private final SubHyperplane plusOutside; + private final SubHyperplane plusOutside; /** Part of the node cut sub-hyperplane that belongs to the * boundary and has the inside of the region on the plus side of * its underlying hyperplane (may be null). */ - private final SubHyperplane plusInside; + private final SubHyperplane plusInside; /** Sub-hyperplanes that were used to split the boundary part. */ - private final NodesSet splitters; + private final NodesSet splitters; /** Simple constructor. * @param plusOutside part of the node cut sub-hyperplane that @@ -62,9 +64,9 @@ public class BoundaryAttribute { * @param splitters sub-hyperplanes that were used to * split the boundary part (may be null) */ - BoundaryAttribute(final SubHyperplane plusOutside, - final SubHyperplane plusInside, - final NodesSet splitters) { + BoundaryAttribute(final SubHyperplane plusOutside, + final SubHyperplane plusInside, + final NodesSet splitters) { this.plusOutside = plusOutside; this.plusInside = plusInside; this.splitters = splitters; @@ -77,7 +79,7 @@ public class BoundaryAttribute { * boundary and has the outside of the region on the plus side of * its underlying hyperplane */ - public SubHyperplane getPlusOutside() { + public SubHyperplane getPlusOutside() { return plusOutside; } @@ -88,14 +90,14 @@ public SubHyperplane getPlusOutside() { * boundary and has the inside of the region on the plus side of * its underlying hyperplane */ - public SubHyperplane getPlusInside() { + public SubHyperplane getPlusInside() { return plusInside; } /** Get the sub-hyperplanes that were used to split the boundary part. * @return sub-hyperplanes that were used to split the boundary part */ - public NodesSet getSplitters() { + public NodesSet getSplitters() { return splitters; } diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/BoundaryBuilder.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/BoundaryBuilder.java index 857da2c7f..bb46981ed 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/BoundaryBuilder.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/BoundaryBuilder.java @@ -21,6 +21,7 @@ */ package org.hipparchus.geometry.partitioning; +import org.hipparchus.geometry.Point; import org.hipparchus.geometry.Space; /** Visitor building boundary shell tree. @@ -29,32 +30,33 @@ * at each internal node. *

* @param Type of the space. + * @param

Type of the points in space. */ -class BoundaryBuilder implements BSPTreeVisitor { +class BoundaryBuilder> implements BSPTreeVisitor { /** {@inheritDoc} */ @Override - public Order visitOrder(BSPTree node) { + public Order visitOrder(BSPTree node) { return Order.PLUS_MINUS_SUB; } /** {@inheritDoc} */ @Override - public void visitInternalNode(BSPTree node) { + public void visitInternalNode(BSPTree node) { - SubHyperplane plusOutside = null; - SubHyperplane plusInside = null; - NodesSet splitters = null; + SubHyperplane plusOutside = null; + SubHyperplane plusInside = null; + NodesSet splitters = null; // characterize the cut sub-hyperplane, // first with respect to the plus sub-tree - final Characterization plusChar = new Characterization<>(node.getPlus(), node.getCut().copySelf()); + final Characterization plusChar = new Characterization<>(node.getPlus(), node.getCut().copySelf()); if (plusChar.touchOutside()) { // plusChar.outsideTouching() corresponds to a subset of the cut sub-hyperplane // known to have outside cells on its plus side, we want to check if parts // of this subset do have inside cells on their minus side - final Characterization minusChar = new Characterization<>(node.getMinus(), plusChar.outsideTouching()); + final Characterization minusChar = new Characterization<>(node.getMinus(), plusChar.outsideTouching()); if (minusChar.touchInside()) { // this part belongs to the boundary, // it has the outside on its plus side and the inside on its minus side @@ -69,7 +71,7 @@ public void visitInternalNode(BSPTree node) { // plusChar.insideTouching() corresponds to a subset of the cut sub-hyperplane // known to have inside cells on its plus side, we want to check if parts // of this subset do have outside cells on their minus side - final Characterization minusChar = new Characterization<>(node.getMinus(), plusChar.insideTouching()); + final Characterization minusChar = new Characterization<>(node.getMinus(), plusChar.insideTouching()); if (minusChar.touchOutside()) { // this part belongs to the boundary, // it has the inside on its plus side and the outside on its minus side @@ -84,7 +86,7 @@ public void visitInternalNode(BSPTree node) { if (splitters != null) { // the parent nodes are natural splitters for boundary sub-hyperplanes - for (BSPTree up = node.getParent(); up != null; up = up.getParent()) { + for (BSPTree up = node.getParent(); up != null; up = up.getParent()) { splitters.add(up); } } @@ -96,7 +98,7 @@ public void visitInternalNode(BSPTree node) { /** {@inheritDoc} */ @Override - public void visitLeafNode(BSPTree node) { + public void visitLeafNode(BSPTree node) { } } diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/BoundaryProjection.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/BoundaryProjection.java index 88cee7709..e4d4fbe64 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/BoundaryProjection.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/BoundaryProjection.java @@ -29,15 +29,16 @@ * processing methods.

*

Instances of this class are guaranteed to be immutable

* @param Type of the space. + * @param

Type of the points in space. * @see AbstractRegion#projectToBoundary(Point) */ -public class BoundaryProjection { +public class BoundaryProjection> { /** Original point. */ - private final Point original; + private final P original; /** Projected point. */ - private final Point projected; + private final P projected; /** Offset of the point with respect to the boundary it is projected on. */ private final double offset; @@ -47,7 +48,7 @@ public class BoundaryProjection { * @param projected projected point * @param offset offset of the point with respect to the boundary it is projected on */ - public BoundaryProjection(final Point original, final Point projected, final double offset) { + public BoundaryProjection(final P original, final P projected, final double offset) { this.original = original; this.projected = projected; this.offset = offset; @@ -56,14 +57,14 @@ public BoundaryProjection(final Point original, final Point projected, fin /** Get the original point. * @return original point */ - public Point getOriginal() { + public P getOriginal() { return original; } /** Projected point. * @return projected point, or null if there are no boundary */ - public Point getProjected() { + public P getProjected() { return projected; } diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/BoundaryProjector.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/BoundaryProjector.java index 890b6cb2a..add3c386f 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/BoundaryProjector.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/BoundaryProjector.java @@ -31,18 +31,20 @@ /** Local tree visitor to compute projection on boundary. * @param Type of the space. + * @param

Type of the points in space. * @param Type of the sub-space. + * @param Type of the points in sub-space. */ -class BoundaryProjector implements BSPTreeVisitor { +class BoundaryProjector, T extends Space, Q extends Point> implements BSPTreeVisitor { /** Original point. */ - private final Point original; + private final P original; /** Current best projected point. */ - private Point projected; + private P projected; /** Leaf node closest to the test point. */ - private BSPTree leaf; + private BSPTree leaf; /** Current offset. */ private double offset; @@ -50,7 +52,7 @@ class BoundaryProjector implements BSPTreeVisi /** Simple constructor. * @param original original point */ - BoundaryProjector(final Point original) { + BoundaryProjector(final P original) { this.original = original; this.projected = null; this.leaf = null; @@ -59,7 +61,7 @@ class BoundaryProjector implements BSPTreeVisi /** {@inheritDoc} */ @Override - public Order visitOrder(final BSPTree node) { + public Order visitOrder(final BSPTree node) { // we want to visit the tree so that the first encountered // leaf is the one closest to the test point if (node.getCut().getHyperplane().getOffset(original) <= 0) { @@ -71,22 +73,22 @@ public Order visitOrder(final BSPTree node) { /** {@inheritDoc} */ @Override - public void visitInternalNode(final BSPTree node) { + public void visitInternalNode(final BSPTree node) { // project the point on the cut sub-hyperplane - final Hyperplane hyperplane = node.getCut().getHyperplane(); + final Hyperplane hyperplane = node.getCut().getHyperplane(); final double signedOffset = hyperplane.getOffset(original); if (FastMath.abs(signedOffset) < offset) { // project point - final Point regular = hyperplane.project(original); + final P regular = hyperplane.project(original); // get boundary parts - final List> boundaryParts = boundaryRegions(node); + final List> boundaryParts = boundaryRegions(node); // check if regular projection really belongs to the boundary boolean regularFound = false; - for (final Region part : boundaryParts) { + for (final Region part : boundaryParts) { if (!regularFound && belongsToPart(regular, hyperplane, part)) { // the projected point lies in the boundary projected = regular; @@ -99,8 +101,8 @@ public void visitInternalNode(final BSPTree node) { // the regular projected point is not on boundary, // so we have to check further if a singular point // (i.e. a vertex in 2D case) is a possible projection - for (final Region part : boundaryParts) { - final Point spI = singularProjection(regular, hyperplane, part); + for (final Region part : boundaryParts) { + final P spI = singularProjection(regular, hyperplane, part); if (spI != null) { final double distance = original.distance(spI); if (distance < offset) { @@ -118,7 +120,7 @@ public void visitInternalNode(final BSPTree node) { /** {@inheritDoc} */ @Override - public void visitLeafNode(final BSPTree node) { + public void visitLeafNode(final BSPTree node) { if (leaf == null) { // this is the first leaf we visit, // it is the closest one to the original point @@ -129,12 +131,12 @@ public void visitLeafNode(final BSPTree node) { /** Get the projection. * @return projection */ - public BoundaryProjection getProjection() { + public BoundaryProjection getProjection() { // fix offset sign offset = FastMath.copySign(offset, (Boolean) leaf.getAttribute() ? -1 : +1); - return new BoundaryProjection(original, projected, offset); + return new BoundaryProjection<>(original, projected, offset); } @@ -142,12 +144,12 @@ public BoundaryProjection getProjection() { * @param node internal node * @return regions in the node sub-hyperplane */ - private List> boundaryRegions(final BSPTree node) { + private List> boundaryRegions(final BSPTree node) { - final List> regions = new ArrayList<>(2); + final List> regions = new ArrayList<>(2); @SuppressWarnings("unchecked") - final BoundaryAttribute ba = (BoundaryAttribute) node.getAttribute(); + final BoundaryAttribute ba = (BoundaryAttribute) node.getAttribute(); addRegion(ba.getPlusInside(), regions); addRegion(ba.getPlusOutside(), regions); @@ -159,10 +161,9 @@ private List> boundaryRegions(final BSPTree node) { * @param sub sub-hyperplane defining the region * @param list to fill up */ - private void addRegion(final SubHyperplane sub, final List> list) { + private void addRegion(final SubHyperplane sub, final List> list) { if (sub != null) { - @SuppressWarnings("unchecked") - final Region region = ((AbstractSubHyperplane) sub).getRemainingRegion(); + final Region region = ((AbstractSubHyperplane) sub).getRemainingRegion(); if (region != null) { list.add(region); } @@ -175,12 +176,12 @@ private void addRegion(final SubHyperplane sub, final List> list) { * @param part boundary part * @return true if point lies on the boundary part */ - private boolean belongsToPart(final Point point, final Hyperplane hyperplane, - final Region part) { + private boolean belongsToPart(final P point, final Hyperplane hyperplane, + final Region part) { // there is a non-null sub-space, we can dive into smaller dimensions @SuppressWarnings("unchecked") - final Embedding embedding = (Embedding) hyperplane; + final Embedding embedding = (Embedding) hyperplane; return part.checkPoint(embedding.toSubSpace(point)) != Location.OUTSIDE; } @@ -191,13 +192,13 @@ private boolean belongsToPart(final Point point, final Hyperplane hyperpla * @param part boundary part * @return projection to a singular point of boundary part (may be null) */ - private Point singularProjection(final Point point, final Hyperplane hyperplane, - final Region part) { + private P singularProjection(final P point, final Hyperplane hyperplane, + final Region part) { // there is a non-null sub-space, we can dive into smaller dimensions @SuppressWarnings("unchecked") - final Embedding embedding = (Embedding) hyperplane; - final BoundaryProjection bp = part.projectToBoundary(embedding.toSubSpace(point)); + final Embedding embedding = (Embedding) hyperplane; + final BoundaryProjection bp = part.projectToBoundary(embedding.toSubSpace(point)); // back to initial dimension return (bp.getProjected() == null) ? null : embedding.toSpace(bp.getProjected()); diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/BoundarySizeVisitor.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/BoundarySizeVisitor.java index 11c737654..7fde7a3d1 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/BoundarySizeVisitor.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/BoundarySizeVisitor.java @@ -21,12 +21,14 @@ */ package org.hipparchus.geometry.partitioning; +import org.hipparchus.geometry.Point; import org.hipparchus.geometry.Space; /** Visitor computing the boundary size. * @param Type of the space. + * @param

Type of the points in space. */ -class BoundarySizeVisitor implements BSPTreeVisitor { +class BoundarySizeVisitor> implements BSPTreeVisitor { /** Size of the boundary. */ private double boundarySize; @@ -39,16 +41,16 @@ class BoundarySizeVisitor implements BSPTreeVisitor { /** {@inheritDoc}*/ @Override - public Order visitOrder(final BSPTree node) { + public Order visitOrder(final BSPTree node) { return Order.MINUS_SUB_PLUS; } /** {@inheritDoc}*/ @Override - public void visitInternalNode(final BSPTree node) { + public void visitInternalNode(final BSPTree node) { @SuppressWarnings("unchecked") - final BoundaryAttribute attribute = - (BoundaryAttribute) node.getAttribute(); + final BoundaryAttribute attribute = + (BoundaryAttribute) node.getAttribute(); if (attribute.getPlusOutside() != null) { boundarySize += attribute.getPlusOutside().getSize(); } @@ -59,7 +61,7 @@ public void visitInternalNode(final BSPTree node) { /** {@inheritDoc}*/ @Override - public void visitLeafNode(final BSPTree node) { + public void visitLeafNode(final BSPTree node) { } /** Get the size of the boundary. diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/Characterization.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/Characterization.java index a64c2a47a..a9b9b6a4a 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/Characterization.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/Characterization.java @@ -25,25 +25,27 @@ import java.util.List; import org.hipparchus.exception.MathRuntimeException; +import org.hipparchus.geometry.Point; import org.hipparchus.geometry.Space; /** Cut sub-hyperplanes characterization with respect to inside/outside cells. * @see BoundaryBuilder * @param Type of the space. + * @param

Type of the points in space. */ -class Characterization { +class Characterization> { /** Part of the cut sub-hyperplane that touch outside cells. */ - private SubHyperplane outsideTouching; + private SubHyperplane outsideTouching; /** Part of the cut sub-hyperplane that touch inside cells. */ - private SubHyperplane insideTouching; + private SubHyperplane insideTouching; /** Nodes that were used to split the outside touching part. */ - private final NodesSet outsideSplitters; + private final NodesSet outsideSplitters; /** Nodes that were used to split the inside touching part. */ - private final NodesSet insideSplitters; + private final NodesSet insideSplitters; /** Simple constructor. *

Characterization consists in splitting the specified @@ -57,7 +59,7 @@ class Characterization { * @param node current BSP tree node * @param sub sub-hyperplane to characterize */ - Characterization(final BSPTree node, final SubHyperplane sub) { + Characterization(final BSPTree node, final SubHyperplane sub) { outsideTouching = null; insideTouching = null; outsideSplitters = new NodesSet<>(); @@ -78,8 +80,8 @@ class Characterization { * @param sub sub-hyperplane to characterize * @param splitters nodes that did split the current one */ - private void characterize(final BSPTree node, final SubHyperplane sub, - final List> splitters) { + private void characterize(final BSPTree node, final SubHyperplane sub, + final List> splitters) { if (node.getCut() == null) { // we have reached a leaf node final boolean inside = (Boolean) node.getAttribute(); @@ -89,8 +91,8 @@ private void characterize(final BSPTree node, final SubHyperplane sub, addOutsideTouching(sub, splitters); } } else { - final Hyperplane hyperplane = node.getCut().getHyperplane(); - final SubHyperplane.SplitSubHyperplane split = sub.split(hyperplane); + final Hyperplane hyperplane = node.getCut().getHyperplane(); + final SubHyperplane.SplitSubHyperplane split = sub.split(hyperplane); switch (split.getSide()) { case PLUS: characterize(node.getPlus(), sub, splitters); @@ -115,8 +117,8 @@ private void characterize(final BSPTree node, final SubHyperplane sub, * @param sub part of the cut sub-hyperplane known to touch an outside cell * @param splitters sub-hyperplanes that did split the current one */ - private void addOutsideTouching(final SubHyperplane sub, - final List> splitters) { + private void addOutsideTouching(final SubHyperplane sub, + final List> splitters) { if (outsideTouching == null) { outsideTouching = sub; } else { @@ -129,8 +131,8 @@ private void addOutsideTouching(final SubHyperplane sub, * @param sub part of the cut sub-hyperplane known to touch an inside cell * @param splitters sub-hyperplanes that did split the current one */ - private void addInsideTouching(final SubHyperplane sub, - final List> splitters) { + private void addInsideTouching(final SubHyperplane sub, + final List> splitters) { if (insideTouching == null) { insideTouching = sub; } else { @@ -150,7 +152,7 @@ public boolean touchOutside() { * @return parts of the cut sub-hyperplane known to touch outside cells * (may be null or empty) */ - public SubHyperplane outsideTouching() { + public SubHyperplane outsideTouching() { return outsideTouching; } @@ -161,7 +163,7 @@ public SubHyperplane outsideTouching() { *

* @return nodes that were used to split the outside touching part */ - public NodesSet getOutsideSplitters() { + public NodesSet getOutsideSplitters() { return outsideSplitters; } @@ -176,7 +178,7 @@ public boolean touchInside() { * @return parts of the cut sub-hyperplane known to touch inside cells * (may be null or empty) */ - public SubHyperplane insideTouching() { + public SubHyperplane insideTouching() { return insideTouching; } @@ -187,7 +189,7 @@ public SubHyperplane insideTouching() { *

* @return nodes that were used to split the inside touching part */ - public NodesSet getInsideSplitters() { + public NodesSet getInsideSplitters() { return insideSplitters; } diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/Embedding.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/Embedding.java index 44097471f..778edfd3c 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/Embedding.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/Embedding.java @@ -47,11 +47,14 @@ *

* @param Type of the embedding space. + * @param

Type of the points in the embedding space. * @param Type of the embedded sub-space. + * @param Type of the points in the embedded sub-space. * @see Hyperplane */ -public interface Embedding { +public interface Embedding, + T extends Space, Q extends Point> { /** Transform a space point into a sub-space point. * @param point n-dimension point of the space @@ -59,7 +62,7 @@ public interface Embedding { * the specified space point * @see #toSpace */ - Point toSubSpace(Point point); + Q toSubSpace(P point); /** Transform a sub-space point into a space point. * @param point (n-1)-dimension point of the sub-space @@ -67,6 +70,6 @@ public interface Embedding { * specified sub-space point * @see #toSubSpace */ - Point toSpace(Point point); + P toSpace(Q point); } diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/Hyperplane.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/Hyperplane.java index 7abf09dff..c4084aad1 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/Hyperplane.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/Hyperplane.java @@ -43,9 +43,10 @@ *

* @param Type of the space. + * @param

Type of the points in space. */ -public interface Hyperplane { +public interface Hyperplane> { /** Copy the instance. *

The instance created is completely independant of the original @@ -53,7 +54,7 @@ public interface Hyperplane { * shared (except for immutable objects).

* @return a new hyperplane, copy of the instance */ - Hyperplane copySelf(); + Hyperplane copySelf(); /** Get the offset (oriented distance) of a point. *

The offset is 0 if the point is on the underlying hyperplane, @@ -63,13 +64,13 @@ public interface Hyperplane { * @param point point to check * @return offset of the point */ - double getOffset(Point point); + double getOffset(P point); /** Project a point to the hyperplane. * @param point point to project * @return projected point */ - Point project(Point point); + P project(P point); /** Get the tolerance below which points are considered to belong to the hyperplane. * @return tolerance below which points are considered to belong to the hyperplane @@ -85,22 +86,22 @@ public interface Hyperplane { * @return true if the instance and the other hyperplane have * the same orientation */ - boolean sameOrientationAs(Hyperplane other); + boolean sameOrientationAs(Hyperplane other); /** Build a sub-hyperplane covering the whole hyperplane. * @return a sub-hyperplane covering the whole hyperplane */ - SubHyperplane wholeHyperplane(); + SubHyperplane wholeHyperplane(); /** Build a sub-hyperplane covering nothing. * @return a sub-hyperplane covering nothing * @since 1.4 */ - SubHyperplane emptyHyperplane(); + SubHyperplane emptyHyperplane(); /** Build a region covering the whole space. * @return a region containing the instance */ - Region wholeSpace(); + Region wholeSpace(); } diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/NodesSet.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/NodesSet.java index 8b1f8a5dc..6896d1cf7 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/NodesSet.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/NodesSet.java @@ -25,16 +25,18 @@ import java.util.Iterator; import java.util.List; +import org.hipparchus.geometry.Point; import org.hipparchus.geometry.Space; /** Set of {@link BSPTree BSP tree} nodes. * @see BoundaryAttribute * @param Type of the space. + * @param

Type of the points in space. */ -public class NodesSet implements Iterable> { +public class NodesSet> implements Iterable> { /** List of sub-hyperplanes. */ - private final List> list; + private final List> list; /** Simple constructor. */ @@ -45,9 +47,9 @@ public NodesSet() { /** Add a node if not already known. * @param node node to add */ - public void add(final BSPTree node) { + public void add(final BSPTree node) { - for (final BSPTree existing : list) { + for (final BSPTree existing : list) { if (node == existing) { // the node is already known, don't add it return; @@ -62,15 +64,15 @@ public void add(final BSPTree node) { /** Add nodes if they are not already known. * @param iterator nodes iterator */ - public void addAll(final Iterable> iterator) { - for (final BSPTree node : iterator) { + public void addAll(final Iterable> iterator) { + for (final BSPTree node : iterator) { add(node); } } /** {@inheritDoc} */ @Override - public Iterator> iterator() { + public Iterator> iterator() { return list.iterator(); } diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/Region.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/Region.java index 4701c4e82..19d02a52e 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/Region.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/Region.java @@ -52,9 +52,10 @@ *

* @param Type of the space. + * @param

Type of the points in the space. */ -public interface Region { +public interface Region> { /** Enumerate for the location of a point with respect to the region. */ enum Location { @@ -65,7 +66,7 @@ enum Location { OUTSIDE, /** Code for points on the partition boundary. */ - BOUNDARY; + BOUNDARY } /** Build a region using the instance as a prototype. @@ -84,7 +85,7 @@ enum Location { * @param newTree inside/outside BSP tree representing the new region * @return the built region */ - Region buildNew(BSPTree newTree); + Region buildNew(BSPTree newTree); /** Copy the instance. *

The instance created is completely independant of the original @@ -93,7 +94,7 @@ enum Location { * attributes and immutable objects).

* @return a new region, copy of the instance */ - Region copySelf(); + Region copySelf(); /** Check if the instance is empty. * @return true if the instance is empty @@ -107,7 +108,7 @@ enum Location { * property) * @return true if the sub-tree starting at the given node is empty */ - boolean isEmpty(BSPTree node); + boolean isEmpty(BSPTree node); /** Check if the instance covers the full space. * @return true if the instance covers the full space @@ -121,26 +122,26 @@ enum Location { * property) * @return true if the sub-tree starting at the given node covers the full space */ - boolean isFull(BSPTree node); + boolean isFull(BSPTree node); /** Check if the instance entirely contains another region. * @param region region to check against the instance * @return true if the instance contains the specified tree */ - boolean contains(Region region); + boolean contains(Region region); /** Check a point with respect to the region. * @param point point to check * @return a code representing the point status: either {@link * Location#INSIDE}, {@link Location#OUTSIDE} or {@link Location#BOUNDARY} */ - Location checkPoint(Point point); + Location checkPoint(P point); /** Project a point on the boundary of the region. * @param point point to check * @return projection of the point on the boundary */ - BoundaryProjection projectToBoundary(Point point); + BoundaryProjection projectToBoundary(P point); /** Get the underlying BSP tree. @@ -181,7 +182,7 @@ enum Location { * @return underlying BSP tree * @see BoundaryAttribute */ - BSPTree getTree(boolean includeBoundaryAttributes); + BSPTree getTree(boolean includeBoundaryAttributes); /** Get the size of the boundary. * @return the size of the boundary (this is 0 in 1D, a length in @@ -198,7 +199,7 @@ enum Location { /** Get the barycenter of the instance. * @return an object representing the barycenter */ - Point getBarycenter(); + P getBarycenter(); /** Get the parts of a sub-hyperplane that are contained in the region. *

The parts of the sub-hyperplane that belong to the boundary are @@ -206,6 +207,6 @@ enum Location { * @param sub sub-hyperplane traversing the region * @return filtered sub-hyperplane */ - SubHyperplane intersection(SubHyperplane sub); + SubHyperplane intersection(SubHyperplane sub); } diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/RegionFactory.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/RegionFactory.java index e06960c06..44b4b0fca 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/RegionFactory.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/RegionFactory.java @@ -35,9 +35,10 @@ /** This class is a factory for {@link Region}. * @param Type of the space. + * @param

Type of the points in space. */ -public class RegionFactory { +public class RegionFactory> { /** Visitor removing internal nodes attributes. */ private final NodesCleaner nodeCleaner; @@ -53,18 +54,18 @@ public RegionFactory() { * @return a new convex region, or null if the collection is empty */ @SafeVarargs - public final Region buildConvex(final Hyperplane ... hyperplanes) { + public final Region buildConvex(final Hyperplane ... hyperplanes) { if ((hyperplanes == null) || (hyperplanes.length == 0)) { return null; } // use the first hyperplane to build the right class - final Region region = hyperplanes[0].wholeSpace(); + final Region region = hyperplanes[0].wholeSpace(); // chop off parts of the space - BSPTree node = region.getTree(false); + BSPTree node = region.getTree(false); node.setAttribute(Boolean.TRUE); - for (final Hyperplane hyperplane : hyperplanes) { + for (final Hyperplane hyperplane : hyperplanes) { if (node.insertCut(hyperplane)) { node.setAttribute(null); node.getPlus().setAttribute(Boolean.FALSE); @@ -74,10 +75,10 @@ public final Region buildConvex(final Hyperplane ... hyperplanes) { // the hyperplane could not be inserted in the current leaf node // either it is completely outside (which means the input hyperplanes // are wrong), or it is parallel to a previous hyperplane - SubHyperplane s = hyperplane.wholeHyperplane(); - for (BSPTree tree = node; tree.getParent() != null && s != null; tree = tree.getParent()) { - final Hyperplane other = tree.getParent().getCut().getHyperplane(); - final SplitSubHyperplane split = s.split(other); + SubHyperplane s = hyperplane.wholeHyperplane(); + for (BSPTree tree = node; tree.getParent() != null && s != null; tree = tree.getParent()) { + final Hyperplane other = tree.getParent().getCut().getHyperplane(); + final SplitSubHyperplane split = s.split(other); switch (split.getSide()) { case HYPER : // the hyperplane is parallel to a previous hyperplane @@ -110,8 +111,8 @@ public final Region buildConvex(final Hyperplane ... hyperplanes) { * parts of it will be reused in the new region) * @return a new region, result of {@code region1 union region2} */ - public Region union(final Region region1, final Region region2) { - final BSPTree tree = + public Region union(final Region region1, final Region region2) { + final BSPTree tree = region1.getTree(false).merge(region2.getTree(false), new UnionMerger()); tree.visit(nodeCleaner); return region1.buildNew(tree); @@ -124,9 +125,9 @@ public Region union(final Region region1, final Region region2) { * parts of it will be reused in the new region) * @return a new region, result of {@code region1 intersection region2} */ - public Region intersection(final Region region1, final Region region2) { - final BSPTree tree = - region1.getTree(false).merge(region2.getTree(false), new IntersectionMerger()); + public Region intersection(final Region region1, final Region region2) { + final BSPTree tree = + region1.getTree(false).merge(region2.getTree(false), new IntersectionMerger(region1, region2)); tree.visit(nodeCleaner); return region1.buildNew(tree); } @@ -138,8 +139,8 @@ public Region intersection(final Region region1, final Region region2) * parts of it will be reused in the new region) * @return a new region, result of {@code region1 xor region2} */ - public Region xor(final Region region1, final Region region2) { - final BSPTree tree = + public Region xor(final Region region1, final Region region2) { + final BSPTree tree = region1.getTree(false).merge(region2.getTree(false), new XorMerger()); tree.visit(nodeCleaner); return region1.buildNew(tree); @@ -152,24 +153,19 @@ public Region xor(final Region region1, final Region region2) { * parts of it will be reused in the new region) * @return a new region, result of {@code region1 minus region2} */ - public Region difference(final Region region1, final Region region2) { - final BSPTree tree = + public Region difference(final Region region1, final Region region2) { + final BSPTree tree = region1.getTree(false).merge(region2.getTree(false), new DifferenceMerger(region1, region2)); tree.visit(nodeCleaner); return region1.buildNew(tree); } - /** Get the complement of the region (exchanged interior/exterior). - * @param region region to complement, it will not modified, a new + /** Get the complement of the region (exchanged interior/exterior). + * @param region region to complement, it will not be modified, a new * region independent region will be built * @return a new region, complement of the specified one */ - /** Get the complement of the region (exchanged interior/exterior). - * @param region region to complement, it will not modified, a new - * region independent region will be built - * @return a new region, complement of the specified one - */ - public Region getComplement(final Region region) { + public Region getComplement(final Region region) { return region.buildNew(recurseComplement(region.getTree(false))); } @@ -177,21 +173,21 @@ public Region getComplement(final Region region) { * @param node current node of the original tree * @return new tree, complement of the node */ - private BSPTree recurseComplement(final BSPTree node) { + private BSPTree recurseComplement(final BSPTree node) { // transform the tree, except for boundary attribute splitters - final Map, BSPTree> map = new HashMap<>(); - final BSPTree transformedTree = recurseComplement(node, map); + final Map, BSPTree> map = new HashMap<>(); + final BSPTree transformedTree = recurseComplement(node, map); // set up the boundary attributes splitters - for (final Map.Entry, BSPTree> entry : map.entrySet()) { + for (final Map.Entry, BSPTree> entry : map.entrySet()) { if (entry.getKey().getCut() != null) { @SuppressWarnings("unchecked") - BoundaryAttribute original = (BoundaryAttribute) entry.getKey().getAttribute(); + BoundaryAttribute original = (BoundaryAttribute) entry.getKey().getAttribute(); if (original != null) { @SuppressWarnings("unchecked") - BoundaryAttribute transformed = (BoundaryAttribute) entry.getValue().getAttribute(); - for (final BSPTree splitter : original.getSplitters()) { + BoundaryAttribute transformed = (BoundaryAttribute) entry.getValue().getAttribute(); + for (final BSPTree splitter : original.getSplitters()) { transformed.getSplitters().add(map.get(splitter)); } } @@ -207,23 +203,23 @@ private BSPTree recurseComplement(final BSPTree node) { * @param map transformed nodes map * @return new tree, complement of the node */ - private BSPTree recurseComplement(final BSPTree node, - final Map, BSPTree> map) { + private BSPTree recurseComplement(final BSPTree node, + final Map, BSPTree> map) { - final BSPTree transformedNode; + final BSPTree transformedNode; if (node.getCut() == null) { transformedNode = new BSPTree<>(((Boolean) node.getAttribute()) ? Boolean.FALSE : Boolean.TRUE); } else { @SuppressWarnings("unchecked") - BoundaryAttribute attribute = (BoundaryAttribute) node.getAttribute(); + BoundaryAttribute attribute = (BoundaryAttribute) node.getAttribute(); if (attribute != null) { - final SubHyperplane plusOutside = + final SubHyperplane plusOutside = (attribute.getPlusInside() == null) ? null : attribute.getPlusInside().copySelf(); - final SubHyperplane plusInside = + final SubHyperplane plusInside = (attribute.getPlusOutside() == null) ? null : attribute.getPlusOutside().copySelf(); // we start with an empty list of splitters, it will be filled in out of recursion - attribute = new BoundaryAttribute<>(plusOutside, plusInside, new NodesSet()); + attribute = new BoundaryAttribute<>(plusOutside, plusInside, new NodesSet<>()); } transformedNode = new BSPTree<>(node.getCut().copySelf(), @@ -237,12 +233,50 @@ private BSPTree recurseComplement(final BSPTree node, } + /** BSP tree leaf merger computing intersection of two regions. */ + private abstract class FixingMerger implements BSPTree.LeafMerger, VanishingCutHandler { + + /** First region. */ + private final Region region1; + + /** Second region. */ + private final Region region2; + + /** Simple constructor. + * @param region1 first region + * @param region2 second region + */ + protected FixingMerger(final Region region1, final Region region2) { + this.region1 = region1.copySelf(); + this.region2 = region2.copySelf(); + } + + /** {@inheritDoc} */ + @Override + public BSPTree fixNode(final BSPTree node) { + // get a representative point in the degenerate cell + final BSPTree cell = node.pruneAroundConvexCell(Boolean.TRUE, Boolean.FALSE, null); + final Region r = region1.buildNew(cell); + final P p = r.getBarycenter(); + return new BSPTree<>(shouldBeInside(region1.checkPoint(p), region2.checkPoint(p))); + } + + /** + * Check if node should be an inside or outside node. + * @param location1 location of representative point in region1 + * @param location2 location of representative point in region2 + * @return true if node should be an inside node + */ + protected abstract boolean shouldBeInside(final Location location1, final Location location2); + + } + /** BSP tree leaf merger computing union of two regions. */ - private class UnionMerger implements BSPTree.LeafMerger { + private class UnionMerger implements BSPTree.LeafMerger { /** {@inheritDoc} */ @Override - public BSPTree merge(final BSPTree leaf, final BSPTree tree, - final BSPTree parentTree, + public BSPTree merge(final BSPTree leaf, final BSPTree tree, + final BSPTree parentTree, final boolean isPlusChild, final boolean leafFromInstance) { if ((Boolean) leaf.getAttribute()) { // the leaf node represents an inside cell @@ -256,31 +290,48 @@ public BSPTree merge(final BSPTree leaf, final BSPTree tree, } /** BSP tree leaf merger computing intersection of two regions. */ - private class IntersectionMerger implements BSPTree.LeafMerger { + private class IntersectionMerger extends FixingMerger { + + /** Simple constructor. + * @param region1 first region + * @param region2 second region + */ + IntersectionMerger(final Region region1, final Region region2) { + super(region1, region2); + } + /** {@inheritDoc} */ @Override - public BSPTree merge(final BSPTree leaf, final BSPTree tree, - final BSPTree parentTree, + public BSPTree merge(final BSPTree leaf, final BSPTree tree, + final BSPTree parentTree, final boolean isPlusChild, final boolean leafFromInstance) { if ((Boolean) leaf.getAttribute()) { // the leaf node represents an inside cell - tree.insertInTree(parentTree, isPlusChild, new VanishingToLeaf(true)); + tree.insertInTree(parentTree, isPlusChild, this); return tree; } // the leaf node represents an outside cell - leaf.insertInTree(parentTree, isPlusChild, new VanishingToLeaf(false)); + leaf.insertInTree(parentTree, isPlusChild, this); return leaf; } + + /** {@inheritDoc} */ + @Override + protected boolean shouldBeInside(final Location location1, final Location location2) + { + return !(location1.equals(Location.OUTSIDE) || location2.equals(Location.OUTSIDE)); + } + } /** BSP tree leaf merger computing symmetric difference (exclusive or) of two regions. */ - private class XorMerger implements BSPTree.LeafMerger { + private class XorMerger implements BSPTree.LeafMerger { /** {@inheritDoc} */ @Override - public BSPTree merge(final BSPTree leaf, final BSPTree tree, - final BSPTree parentTree, final boolean isPlusChild, + public BSPTree merge(final BSPTree leaf, final BSPTree tree, + final BSPTree parentTree, final boolean isPlusChild, final boolean leafFromInstance) { - BSPTree t = tree; + BSPTree t = tree; if ((Boolean) leaf.getAttribute()) { // the leaf node represents an inside cell t = recurseComplement(t); @@ -291,37 +342,30 @@ public BSPTree merge(final BSPTree leaf, final BSPTree tree, } /** BSP tree leaf merger computing difference of two regions. */ - private class DifferenceMerger implements BSPTree.LeafMerger, VanishingCutHandler { - - /** Region to subtract from. */ - private final Region region1; - - /** Region to subtract. */ - private final Region region2; + private class DifferenceMerger extends FixingMerger { /** Simple constructor. * @param region1 region to subtract from * @param region2 region to subtract */ - DifferenceMerger(final Region region1, final Region region2) { - this.region1 = region1.copySelf(); - this.region2 = region2.copySelf(); + DifferenceMerger(final Region region1, final Region region2) { + super(region1, region2); } /** {@inheritDoc} */ @Override - public BSPTree merge(final BSPTree leaf, final BSPTree tree, - final BSPTree parentTree, final boolean isPlusChild, + public BSPTree merge(final BSPTree leaf, final BSPTree tree, + final BSPTree parentTree, final boolean isPlusChild, final boolean leafFromInstance) { if ((Boolean) leaf.getAttribute()) { // the leaf node represents an inside cell - final BSPTree argTree = + final BSPTree argTree = recurseComplement(leafFromInstance ? tree : leaf); argTree.insertInTree(parentTree, isPlusChild, this); return argTree; } // the leaf node represents an outside cell - final BSPTree instanceTree = + final BSPTree instanceTree = leafFromInstance ? leaf : tree; instanceTree.insertInTree(parentTree, isPlusChild, this); return instanceTree; @@ -329,43 +373,38 @@ public BSPTree merge(final BSPTree leaf, final BSPTree tree, /** {@inheritDoc} */ @Override - public BSPTree fixNode(final BSPTree node) { - // get a representative point in the degenerate cell - final BSPTree cell = node.pruneAroundConvexCell(Boolean.TRUE, Boolean.FALSE, null); - final Region r = region1.buildNew(cell); - final Point p = r.getBarycenter(); - return new BSPTree(region1.checkPoint(p) == Location.INSIDE && - region2.checkPoint(p) == Location.OUTSIDE); + protected boolean shouldBeInside(final Location location1, final Location location2) { + return location1 == Location.INSIDE && location2 == Location.OUTSIDE; } } /** Visitor removing internal nodes attributes. */ - private class NodesCleaner implements BSPTreeVisitor { + private class NodesCleaner implements BSPTreeVisitor { /** {@inheritDoc} */ @Override - public Order visitOrder(final BSPTree node) { + public Order visitOrder(final BSPTree node) { return Order.PLUS_SUB_MINUS; } /** {@inheritDoc} */ @Override - public void visitInternalNode(final BSPTree node) { + public void visitInternalNode(final BSPTree node) { node.setAttribute(null); } /** {@inheritDoc} */ @Override - public void visitLeafNode(final BSPTree node) { + public void visitLeafNode(final BSPTree node) { } } /** Handler replacing nodes with vanishing cuts with leaf nodes. */ - private class VanishingToLeaf implements VanishingCutHandler { + private class VanishingToLeaf implements VanishingCutHandler { - /** Inside/outside indocator to use for ambiguous nodes. */ + /** Inside/outside indicator to use for ambiguous nodes. */ private final boolean inside; /** Simple constructor. @@ -377,13 +416,13 @@ private class VanishingToLeaf implements VanishingCutHandler { /** {@inheritDoc} */ @Override - public BSPTree fixNode(final BSPTree node) { + public BSPTree fixNode(final BSPTree node) { if (node.getPlus().getAttribute().equals(node.getMinus().getAttribute())) { // no ambiguity - return new BSPTree(node.getPlus().getAttribute()); + return new BSPTree<>(node.getPlus().getAttribute()); } else { // ambiguous node - return new BSPTree(inside); + return new BSPTree<>(inside); } } diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/SubHyperplane.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/SubHyperplane.java index 5b9b1424f..c7ab0f7f8 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/SubHyperplane.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/SubHyperplane.java @@ -21,6 +21,7 @@ */ package org.hipparchus.geometry.partitioning; +import org.hipparchus.geometry.Point; import org.hipparchus.geometry.Space; /** This interface represents the remaining parts of an hyperplane after @@ -40,10 +41,11 @@ * versions, which breaks compatibility for external implementations. *

- * @param Type of the embedding space. + * @param Type of the space. + * @param

Type of the points in space. */ -public interface SubHyperplane { +public interface SubHyperplane> { /** Copy the instance. *

The instance created is completely independent of the original @@ -52,12 +54,12 @@ public interface SubHyperplane { * objects).

* @return a new sub-hyperplane, copy of the instance */ - SubHyperplane copySelf(); + SubHyperplane copySelf(); /** Get the underlying hyperplane. * @return underlying hyperplane */ - Hyperplane getHyperplane(); + Hyperplane getHyperplane(); /** Check if the instance is empty. * @return true if the instance is empty @@ -76,25 +78,26 @@ public interface SubHyperplane { * on the plus side of the hyperplane and the part of the * instance on the minus side of the hyperplane */ - SplitSubHyperplane split(Hyperplane hyperplane); + SplitSubHyperplane split(Hyperplane hyperplane); /** Compute the union of the instance and another sub-hyperplane. * @param other other sub-hyperplane to union (must be in the * same hyperplane as the instance) * @return a new sub-hyperplane, union of the instance and other */ - SubHyperplane reunite(SubHyperplane other); + SubHyperplane reunite(SubHyperplane other); /** Class holding the results of the {@link #split split} method. * @param Type of the embedding space. + * @param Type of the points in the embedding space. */ - class SplitSubHyperplane { + class SplitSubHyperplane> { /** Part of the sub-hyperplane on the plus side of the splitting hyperplane. */ - private final SubHyperplane plus; + private final SubHyperplane plus; /** Part of the sub-hyperplane on the minus side of the splitting hyperplane. */ - private final SubHyperplane minus; + private final SubHyperplane minus; /** Build a SplitSubHyperplane from its parts. * @param plus part of the sub-hyperplane on the plus side of the @@ -102,8 +105,8 @@ class SplitSubHyperplane { * @param minus part of the sub-hyperplane on the minus side of the * splitting hyperplane */ - public SplitSubHyperplane(final SubHyperplane plus, - final SubHyperplane minus) { + public SplitSubHyperplane(final SubHyperplane plus, + final SubHyperplane minus) { this.plus = plus; this.minus = minus; } @@ -111,14 +114,14 @@ public SplitSubHyperplane(final SubHyperplane plus, /** Get the part of the sub-hyperplane on the plus side of the splitting hyperplane. * @return part of the sub-hyperplane on the plus side of the splitting hyperplane */ - public SubHyperplane getPlus() { + public SubHyperplane getPlus() { return plus; } /** Get the part of the sub-hyperplane on the minus side of the splitting hyperplane. * @return part of the sub-hyperplane on the minus side of the splitting hyperplane */ - public SubHyperplane getMinus() { + public SubHyperplane getMinus() { return minus; } diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/Transform.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/Transform.java index 9c84933cd..5415124f3 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/Transform.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/partitioning/Transform.java @@ -51,23 +51,26 @@ * * - * @param Type of the embedding space. - * @param Type of the embedded sub-space. + * @param Type of the space. + * @param

Type of the points in the space. + * @param Type of the sub-space. + * @param Type of the points in the sub-space. */ -public interface Transform { +public interface Transform, + T extends Space, Q extends Point> { /** Transform a point of a space. * @param point point to transform * @return a new object representing the transformed point */ - Point apply(Point point); + P apply(P point); /** Transform an hyperplane of a space. * @param hyperplane hyperplane to transform * @return a new object representing the transformed hyperplane */ - Hyperplane apply(Hyperplane hyperplane); + Hyperplane apply(Hyperplane hyperplane); /** Transform a sub-hyperplane embedded in an hyperplane. * @param sub sub-hyperplane to transform @@ -79,6 +82,6 @@ public interface Transform { * has been applied to it) * @return a new object representing the transformed sub-hyperplane */ - SubHyperplane apply(SubHyperplane sub, Hyperplane original, Hyperplane transformed); + SubHyperplane apply(SubHyperplane sub, Hyperplane original, Hyperplane transformed); } diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/spherical/oned/ArcsSet.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/spherical/oned/ArcsSet.java index 3640ee901..75c755e69 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/spherical/oned/ArcsSet.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/spherical/oned/ArcsSet.java @@ -29,9 +29,9 @@ import org.hipparchus.exception.LocalizedCoreFormats; import org.hipparchus.exception.MathIllegalArgumentException; +import org.hipparchus.exception.MathIllegalStateException; import org.hipparchus.exception.MathRuntimeException; import org.hipparchus.geometry.LocalizedGeometryFormats; -import org.hipparchus.geometry.Point; import org.hipparchus.geometry.partitioning.AbstractRegion; import org.hipparchus.geometry.partitioning.BSPTree; import org.hipparchus.geometry.partitioning.BoundaryProjection; @@ -50,7 +50,7 @@ * interface, but its use is discouraged. *

*/ -public class ArcsSet extends AbstractRegion implements Iterable { +public class ArcsSet extends AbstractRegion implements Iterable { /** Build an arcs set representing the whole circle. * @param tolerance tolerance below which close sub-arcs are merged together @@ -95,7 +95,7 @@ public ArcsSet(final double lower, final double upper, final double tolerance) * consistent across the \( 0, 2 \pi \) crossing * @exception MathIllegalArgumentException if tolerance is smaller than {@link Sphere1D#SMALLEST_TOLERANCE} */ - public ArcsSet(final BSPTree tree, final double tolerance) + public ArcsSet(final BSPTree tree, final double tolerance) throws InconsistentStateAt2PiWrapping, MathIllegalArgumentException { super(tree, tolerance); Sphere1D.checkTolerance(tolerance); @@ -125,7 +125,7 @@ public ArcsSet(final BSPTree tree, final double tolerance) * consistent across the \( 0, 2 \pi \) crossing * @exception MathIllegalArgumentException if tolerance is smaller than {@link Sphere1D#SMALLEST_TOLERANCE} */ - public ArcsSet(final Collection> boundary, final double tolerance) + public ArcsSet(final Collection> boundary, final double tolerance) throws InconsistentStateAt2PiWrapping, MathIllegalArgumentException { super(boundary, tolerance); Sphere1D.checkTolerance(tolerance); @@ -140,14 +140,14 @@ public ArcsSet(final Collection> boundary, final double * @exception MathIllegalArgumentException if lower is greater than upper * or tolerance is smaller than {@link Sphere1D#SMALLEST_TOLERANCE} */ - private static BSPTree buildTree(final double lower, final double upper, - final double tolerance) + private static BSPTree buildTree(final double lower, final double upper, + final double tolerance) throws MathIllegalArgumentException { Sphere1D.checkTolerance(tolerance); if (Precision.equals(lower, upper, 0) || (upper - lower) >= MathUtils.TWO_PI) { // the tree must cover the whole circle - return new BSPTree(Boolean.TRUE); + return new BSPTree<>(Boolean.TRUE); } else if (lower > upper) { throw new MathIllegalArgumentException(LocalizedCoreFormats.ENDPOINTS_NOT_AN_INTERVAL, lower, upper, true); @@ -156,31 +156,31 @@ private static BSPTree buildTree(final double lower, final double uppe // this is a regular arc, covering only part of the circle final double normalizedLower = MathUtils.normalizeAngle(lower, FastMath.PI); final double normalizedUpper = normalizedLower + (upper - lower); - final SubHyperplane lowerCut = + final SubHyperplane lowerCut = new LimitAngle(new S1Point(normalizedLower), false, tolerance).wholeHyperplane(); if (normalizedUpper <= MathUtils.TWO_PI) { // simple arc starting after 0 and ending before 2 \pi - final SubHyperplane upperCut = + final SubHyperplane upperCut = new LimitAngle(new S1Point(normalizedUpper), true, tolerance).wholeHyperplane(); - return new BSPTree(lowerCut, - new BSPTree(Boolean.FALSE), - new BSPTree(upperCut, - new BSPTree(Boolean.FALSE), - new BSPTree(Boolean.TRUE), - null), - null); + return new BSPTree<>(lowerCut, + new BSPTree<>(Boolean.FALSE), + new BSPTree<>(upperCut, + new BSPTree<>(Boolean.FALSE), + new BSPTree<>(Boolean.TRUE), + null), + null); } else { // arc wrapping around 2 \pi - final SubHyperplane upperCut = + final SubHyperplane upperCut = new LimitAngle(new S1Point(normalizedUpper - MathUtils.TWO_PI), true, tolerance).wholeHyperplane(); - return new BSPTree(lowerCut, - new BSPTree(upperCut, - new BSPTree(Boolean.FALSE), - new BSPTree(Boolean.TRUE), - null), - new BSPTree(Boolean.TRUE), - null); + return new BSPTree<>(lowerCut, + new BSPTree<>(upperCut, + new BSPTree<>(Boolean.FALSE), + new BSPTree<>(Boolean.TRUE), + null), + new BSPTree<>(Boolean.TRUE), + null); } } @@ -192,7 +192,7 @@ private static BSPTree buildTree(final double lower, final double uppe private void check2PiConsistency() throws InconsistentStateAt2PiWrapping { // start search at the tree root - BSPTree root = getTree(false); + BSPTree root = getTree(false); if (root.getCut() == null) { return; } @@ -213,15 +213,15 @@ private void check2PiConsistency() throws InconsistentStateAt2PiWrapping { * @param root tree root * @return first leaf node (i.e. node corresponding to the region just after 0.0 radians) */ - private BSPTree getFirstLeaf(final BSPTree root) { + private BSPTree getFirstLeaf(final BSPTree root) { if (root.getCut() == null) { return root; } // find the smallest internal node - BSPTree smallest = null; - for (BSPTree n = root; n != null; n = previousInternalNode(n)) { + BSPTree smallest = null; + for (BSPTree n = root; n != null; n = previousInternalNode(n)) { smallest = n; } @@ -233,15 +233,15 @@ private BSPTree getFirstLeaf(final BSPTree root) { * @param root tree root * @return last leaf node (i.e. node corresponding to the region just before \( 2 \pi \) radians) */ - private BSPTree getLastLeaf(final BSPTree root) { + private BSPTree getLastLeaf(final BSPTree root) { if (root.getCut() == null) { return root; } // find the largest internal node - BSPTree largest = null; - for (BSPTree n = root; n != null; n = nextInternalNode(n)) { + BSPTree largest = null; + for (BSPTree n = root; n != null; n = nextInternalNode(n)) { largest = n; } @@ -253,10 +253,10 @@ private BSPTree getLastLeaf(final BSPTree root) { * @return smallest internal node (i.e. first after 0.0 radians, in trigonometric direction), * or null if there are no internal nodes (i.e. the set is either empty or covers the full circle) */ - private BSPTree getFirstArcStart() { + private BSPTree getFirstArcStart() { // start search at the tree root - BSPTree node = getTree(false); + BSPTree node = getTree(false); if (node.getCut() == null) { return null; } @@ -277,7 +277,7 @@ private BSPTree getFirstArcStart() { * @param node internal node to check * @return true if the node corresponds to the start angle of an arc */ - private boolean isArcStart(final BSPTree node) { + private boolean isArcStart(final BSPTree node) { if ((Boolean) leafBefore(node).getAttribute()) { // it has an inside cell before it, it may end an arc but not start it @@ -299,7 +299,7 @@ private boolean isArcStart(final BSPTree node) { * @param node internal node to check * @return true if the node corresponds to the end angle of an arc */ - private boolean isArcEnd(final BSPTree node) { + private boolean isArcEnd(final BSPTree node) { if (!(Boolean) leafBefore(node).getAttribute()) { // it has an outside cell before it, it may start an arc but not end it @@ -322,7 +322,7 @@ private boolean isArcEnd(final BSPTree node) { * @return next internal node in trigonometric order, or null * if this is the last internal node */ - private BSPTree nextInternalNode(BSPTree node) { + private BSPTree nextInternalNode(BSPTree node) { if (childAfter(node).getCut() != null) { // the next node is in the sub-tree @@ -342,7 +342,7 @@ private BSPTree nextInternalNode(BSPTree node) { * @return previous internal node in trigonometric order, or null * if this is the first internal node */ - private BSPTree previousInternalNode(BSPTree node) { + private BSPTree previousInternalNode(BSPTree node) { if (childBefore(node).getCut() != null) { // the next node is in the sub-tree @@ -361,7 +361,7 @@ private BSPTree previousInternalNode(BSPTree node) { * @param node internal node at which the sub-tree starts * @return leaf node just before the internal node */ - private BSPTree leafBefore(BSPTree node) { + private BSPTree leafBefore(BSPTree node) { node = childBefore(node); while (node.getCut() != null) { @@ -376,7 +376,7 @@ private BSPTree leafBefore(BSPTree node) { * @param node internal node at which the sub-tree starts * @return leaf node just after the internal node */ - private BSPTree leafAfter(BSPTree node) { + private BSPTree leafAfter(BSPTree node) { node = childAfter(node); while (node.getCut() != null) { @@ -391,8 +391,8 @@ private BSPTree leafAfter(BSPTree node) { * @param node child node considered * @return true is the node has a parent end is before it in trigonometric order */ - private boolean isBeforeParent(final BSPTree node) { - final BSPTree parent = node.getParent(); + private boolean isBeforeParent(final BSPTree node) { + final BSPTree parent = node.getParent(); if (parent == null) { return false; } else { @@ -404,8 +404,8 @@ private boolean isBeforeParent(final BSPTree node) { * @param node child node considered * @return true is the node has a parent end is after it in trigonometric order */ - private boolean isAfterParent(final BSPTree node) { - final BSPTree parent = node.getParent(); + private boolean isAfterParent(final BSPTree node) { + final BSPTree parent = node.getParent(); if (parent == null) { return false; } else { @@ -417,7 +417,7 @@ private boolean isAfterParent(final BSPTree node) { * @param node internal node at which the sub-tree starts * @return child node just before the internal node */ - private BSPTree childBefore(BSPTree node) { + private BSPTree childBefore(BSPTree node) { if (isDirect(node)) { // smaller angles are on minus side, larger angles are on plus side return node.getMinus(); @@ -431,7 +431,7 @@ private BSPTree childBefore(BSPTree node) { * @param node internal node at which the sub-tree starts * @return child node just after the internal node */ - private BSPTree childAfter(BSPTree node) { + private BSPTree childAfter(BSPTree node) { if (isDirect(node)) { // smaller angles are on minus side, larger angles are on plus side return node.getPlus(); @@ -445,7 +445,7 @@ private BSPTree childAfter(BSPTree node) { * @param node internal node to check * @return true if the limit angle is direct */ - private boolean isDirect(final BSPTree node) { + private boolean isDirect(final BSPTree node) { return ((LimitAngle) node.getCut().getHyperplane()).isDirect(); } @@ -453,13 +453,13 @@ private boolean isDirect(final BSPTree node) { * @param node internal node to check * @return limit angle */ - private double getAngle(final BSPTree node) { + private double getAngle(final BSPTree node) { return ((LimitAngle) node.getCut().getHyperplane()).getLocation().getAlpha(); } /** {@inheritDoc} */ @Override - public ArcsSet buildNew(final BSPTree tree) { + public ArcsSet buildNew(final BSPTree tree) { return new ArcsSet(tree, getTolerance()); } @@ -492,10 +492,10 @@ protected void computeGeometricalProperties() { /** {@inheritDoc} */ @Override - public BoundaryProjection projectToBoundary(final Point point) { + public BoundaryProjection projectToBoundary(final S1Point point) { // get position of test point - final double alpha = ((S1Point) point).getAlpha(); + final double alpha = point.getAlpha(); boolean wrapFirst = false; double first = Double.NaN; @@ -518,9 +518,9 @@ public BoundaryProjection projectToBoundary(final Point poin final double previousOffset = alpha - previous; final double currentOffset = a[0] - alpha; if (previousOffset < currentOffset) { - return new BoundaryProjection(point, new S1Point(previous), previousOffset); + return new BoundaryProjection<>(point, new S1Point(previous), previousOffset); } else { - return new BoundaryProjection(point, new S1Point(a[0]), currentOffset); + return new BoundaryProjection<>(point, new S1Point(a[0]), currentOffset); } } } else if (alpha <= a[1]) { @@ -529,9 +529,9 @@ public BoundaryProjection projectToBoundary(final Point poin final double offset0 = a[0] - alpha; final double offset1 = alpha - a[1]; if (offset0 < offset1) { - return new BoundaryProjection(point, new S1Point(a[1]), offset1); + return new BoundaryProjection<>(point, new S1Point(a[1]), offset1); } else { - return new BoundaryProjection(point, new S1Point(a[0]), offset0); + return new BoundaryProjection<>(point, new S1Point(a[0]), offset0); } } } @@ -541,7 +541,7 @@ public BoundaryProjection projectToBoundary(final Point poin if (Double.isNaN(previous)) { // there are no points at all in the arcs set - return new BoundaryProjection(point, null, MathUtils.TWO_PI); + return new BoundaryProjection<>(point, null, MathUtils.TWO_PI); } else { @@ -552,18 +552,18 @@ public BoundaryProjection projectToBoundary(final Point poin final double previousOffset = alpha - (previous - MathUtils.TWO_PI); final double currentOffset = first - alpha; if (previousOffset < currentOffset) { - return new BoundaryProjection(point, new S1Point(previous), previousOffset); + return new BoundaryProjection<>(point, new S1Point(previous), previousOffset); } else { - return new BoundaryProjection(point, new S1Point(first), currentOffset); + return new BoundaryProjection<>(point, new S1Point(first), currentOffset); } } else { // the test point is between last and 2\pi final double previousOffset = alpha - previous; final double currentOffset = first + MathUtils.TWO_PI - alpha; if (previousOffset < currentOffset) { - return new BoundaryProjection(point, new S1Point(previous), previousOffset); + return new BoundaryProjection<>(point, new S1Point(previous), previousOffset); } else { - return new BoundaryProjection(point, new S1Point(first), currentOffset); + return new BoundaryProjection<>(point, new S1Point(first), currentOffset); } } @@ -603,10 +603,10 @@ public Iterator iterator() { private class SubArcsIterator implements Iterator { /** Start of the first arc. */ - private final BSPTree firstStart; + private final BSPTree firstStart; /** Current node. */ - private BSPTree current; + private BSPTree current; /** Sub-arc no yet returned. */ private double[] pending; @@ -638,7 +638,7 @@ private class SubArcsIterator implements Iterator { private void selectPending() { // look for the start of the arc - BSPTree start = current; + BSPTree start = current; while (start != null && !isArcStart(start)) { start = nextInternalNode(start); } @@ -651,7 +651,7 @@ private void selectPending() { } // look for the end of the arc - BSPTree end = start; + BSPTree end = start; while (end != null && !isArcEnd(end)) { end = nextInternalNode(end); } @@ -793,10 +793,10 @@ public Split split(final Arc arc) { * @param alpha arc limit * @param isStart if true, the limit is the start of an arc */ - private void addArcLimit(final BSPTree tree, final double alpha, final boolean isStart) { + private void addArcLimit(final BSPTree tree, final double alpha, final boolean isStart) { final LimitAngle limit = new LimitAngle(new S1Point(alpha), !isStart, getTolerance()); - final BSPTree node = tree.getCell(limit.getLocation(), getTolerance()); + final BSPTree node = tree.getCell(limit.getLocation(), getTolerance()); if (node.getCut() != null) { // this should never happen throw MathRuntimeException.createInternalError(); @@ -844,7 +844,7 @@ private ArcsSet createSplitPart(final List limits) { // the ends were the only limits, is it a full circle or an empty circle? if (lEnd - lStart > FastMath.PI) { // it was full circle - return new ArcsSet(new BSPTree(Boolean.TRUE), getTolerance()); + return new ArcsSet(new BSPTree<>(Boolean.TRUE), getTolerance()); } else { // it was an empty circle return null; @@ -860,7 +860,7 @@ private ArcsSet createSplitPart(final List limits) { } // build the tree by adding all angular sectors - BSPTree tree = new BSPTree<>(Boolean.FALSE); + BSPTree tree = new BSPTree<>(Boolean.FALSE); for (int i = 0; i < limits.size() - 1; i += 2) { addArcLimit(tree, limits.get(i), true); addArcLimit(tree, limits.get(i + 1), false); @@ -941,7 +941,8 @@ public Side getSide() { * state is not consistent at the 0, \(2 \pi \) crossing. *

*/ - public static class InconsistentStateAt2PiWrapping extends MathIllegalArgumentException { + public static class InconsistentStateAt2PiWrapping extends MathIllegalStateException + { /** Serializable UID. */ private static final long serialVersionUID = 20140107L; diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/spherical/oned/LimitAngle.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/spherical/oned/LimitAngle.java index 0f3837b0a..c1f01ac63 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/spherical/oned/LimitAngle.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/spherical/oned/LimitAngle.java @@ -22,14 +22,13 @@ package org.hipparchus.geometry.spherical.oned; import org.hipparchus.exception.MathIllegalArgumentException; -import org.hipparchus.geometry.Point; import org.hipparchus.geometry.partitioning.Hyperplane; /** This class represents a 1D oriented hyperplane on the circle. *

An hyperplane on the 1-sphere is an angle with an orientation.

*

Instances of this class are guaranteed to be immutable.

*/ -public class LimitAngle implements Hyperplane { +public class LimitAngle implements Hyperplane { /** Angle location. */ private final S1Point location; @@ -67,8 +66,8 @@ public LimitAngle copySelf() { /** {@inheritDoc} */ @Override - public double getOffset(final Point point) { - final double delta = ((S1Point) point).getAlpha() - location.getAlpha(); + public double getOffset(final S1Point point) { + final double delta = point.getAlpha() - location.getAlpha(); return direct ? delta : -delta; } @@ -131,8 +130,8 @@ public ArcsSet wholeSpace() { /** {@inheritDoc} */ @Override - public boolean sameOrientationAs(final Hyperplane other) { - return !(direct ^ ((LimitAngle) other).direct); + public boolean sameOrientationAs(final Hyperplane other) { + return direct == ((LimitAngle) other).direct; } /** Get the hyperplane location on the circle. @@ -144,7 +143,7 @@ public S1Point getLocation() { /** {@inheritDoc} */ @Override - public Point project(Point point) { + public S1Point project(S1Point point) { return location; } diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/spherical/oned/SubLimitAngle.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/spherical/oned/SubLimitAngle.java index d14c4c557..85fc97a47 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/spherical/oned/SubLimitAngle.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/spherical/oned/SubLimitAngle.java @@ -28,14 +28,14 @@ /** This class represents sub-hyperplane for {@link LimitAngle}. *

Instances of this class are guaranteed to be immutable.

*/ -public class SubLimitAngle extends AbstractSubHyperplane { +public class SubLimitAngle extends AbstractSubHyperplane { /** Simple constructor. * @param hyperplane underlying hyperplane * @param remainingRegion remaining region of the hyperplane */ - public SubLimitAngle(final Hyperplane hyperplane, - final Region remainingRegion) { + public SubLimitAngle(final Hyperplane hyperplane, + final Region remainingRegion) { super(hyperplane, remainingRegion); } @@ -53,21 +53,22 @@ public boolean isEmpty() { /** {@inheritDoc} */ @Override - protected AbstractSubHyperplane buildNew(final Hyperplane hyperplane, - final Region remainingRegion) { + protected AbstractSubHyperplane + buildNew(final Hyperplane hyperplane, + final Region remainingRegion) { return new SubLimitAngle(hyperplane, remainingRegion); } /** {@inheritDoc} */ @Override - public SplitSubHyperplane split(final Hyperplane hyperplane) { + public SplitSubHyperplane split(final Hyperplane hyperplane) { final double global = hyperplane.getOffset(((LimitAngle) getHyperplane()).getLocation()); if (global < -hyperplane.getTolerance()) { - return new SplitSubHyperplane(null, this); + return new SplitSubHyperplane<>(null, this); } else if (global > hyperplane.getTolerance()) { - return new SplitSubHyperplane(this, null); + return new SplitSubHyperplane<>(this, null); } else { - return new SplitSubHyperplane(null, null); + return new SplitSubHyperplane<>(null, null); } } diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/spherical/twod/Circle.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/spherical/twod/Circle.java index ad0f35db4..2f9cfdee9 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/spherical/twod/Circle.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/spherical/twod/Circle.java @@ -49,7 +49,7 @@ * a spherical polygon boundary.

*/ -public class Circle implements Hyperplane, Embedding { +public class Circle implements Hyperplane, Embedding { /** Pole or circle center. */ private Vector3D pole; @@ -151,7 +151,7 @@ public Circle getReverse() { /** {@inheritDoc} */ @Override - public Point project(Point point) { + public S2Point project(S2Point point) { return toSpace(toSubSpace(point)); } @@ -165,8 +165,8 @@ public double getTolerance() { * @see #getPhase(Vector3D) */ @Override - public S1Point toSubSpace(final Point point) { - return new S1Point(getPhase(((S2Point) point).getVector())); + public S1Point toSubSpace(final S2Point point) { + return new S1Point(getPhase(point.getVector())); } /** Get the phase angle of a direction. @@ -177,7 +177,7 @@ public S1Point toSubSpace(final Point point) { *

* @param direction direction for which phase is requested * @return phase angle of the direction around the circle - * @see #toSubSpace(Point) + * @see #toSubSpace(S2Point) */ public double getPhase(final Vector3D direction) { return FastMath.PI + FastMath.atan2(-direction.dotProduct(y), -direction.dotProduct(x)); @@ -187,14 +187,14 @@ public double getPhase(final Vector3D direction) { * @see #getPointAt(double) */ @Override - public S2Point toSpace(final Point point) { - return new S2Point(getPointAt(((S1Point) point).getAlpha())); + public S2Point toSpace(final S1Point point) { + return new S2Point(getPointAt(point.getAlpha())); } /** Get a circle point from its phase around the circle. * @param alpha phase around the circle * @return circle point on the sphere - * @see #toSpace(Point) + * @see #toSpace(S1Point) * @see #getXAxis() * @see #getYAxis() */ @@ -265,7 +265,7 @@ public SubCircle wholeHyperplane() { /** {@inheritDoc} */ @Override public SubCircle emptyHyperplane() { - return new SubCircle(this, new RegionFactory().getComplement(new ArcsSet(tolerance))); + return new SubCircle(this, new RegionFactory().getComplement(new ArcsSet(tolerance))); } /** Build a region covering the whole space. @@ -281,8 +281,8 @@ public SphericalPolygonsSet wholeSpace() { * @see #getOffset(Vector3D) */ @Override - public double getOffset(final Point point) { - return getOffset(((S2Point) point).getVector()); + public double getOffset(final S2Point point) { + return getOffset(point.getVector()); } /** Get the offset (oriented distance) of a direction. @@ -292,7 +292,7 @@ public double getOffset(final Point point) { * the cone delimited by the circle, and negative inside the cone.

* @param direction direction to check * @return offset of the direction - * @see #getOffset(Point) + * @see #getOffset(S2Point) */ public double getOffset(final Vector3D direction) { return Vector3D.angle(pole, direction) - 0.5 * FastMath.PI; @@ -300,7 +300,7 @@ public double getOffset(final Vector3D direction) { /** {@inheritDoc} */ @Override - public boolean sameOrientationAs(final Hyperplane other) { + public boolean sameOrientationAs(final Hyperplane other) { final Circle otherC = (Circle) other; return Vector3D.dotProduct(pole, otherC.pole) >= 0.0; } @@ -330,12 +330,12 @@ public Arc getArc(final S2Point a, final S2Point b) { * org.hipparchus.geometry.partitioning.SubHyperplane * SubHyperplane} instances */ - public static Transform getTransform(final Rotation rotation) { + public static Transform getTransform(final Rotation rotation) { return new CircleTransform(rotation); } /** Class embedding a 3D rotation. */ - private static class CircleTransform implements Transform { + private static class CircleTransform implements Transform { /** Underlying rotation. */ private final Rotation rotation; @@ -349,13 +349,13 @@ private static class CircleTransform implements Transform { /** {@inheritDoc} */ @Override - public S2Point apply(final Point point) { - return new S2Point(rotation.applyTo(((S2Point) point).getVector())); + public S2Point apply(final S2Point point) { + return new S2Point(rotation.applyTo(point.getVector())); } /** {@inheritDoc} */ @Override - public Circle apply(final Hyperplane hyperplane) { + public Circle apply(final Hyperplane hyperplane) { final Circle circle = (Circle) hyperplane; return new Circle(rotation.applyTo(circle.pole), rotation.applyTo(circle.x), @@ -365,9 +365,9 @@ public Circle apply(final Hyperplane hyperplane) { /** {@inheritDoc} */ @Override - public SubHyperplane apply(final SubHyperplane sub, - final Hyperplane original, - final Hyperplane transformed) { + public SubHyperplane apply(final SubHyperplane sub, + final Hyperplane original, + final Hyperplane transformed) { // as the circle is rotated, the limit angles are rotated too return sub; } diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/spherical/twod/EdgeWithNodeInfo.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/spherical/twod/EdgeWithNodeInfo.java index c0cd250b6..7777a3547 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/spherical/twod/EdgeWithNodeInfo.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/spherical/twod/EdgeWithNodeInfo.java @@ -32,13 +32,13 @@ class EdgeWithNodeInfo extends Edge { /** Node containing edge. */ - private final BSPTree node; + private final BSPTree node; /** Node whose intersection with current node defines start point. */ - private final BSPTree startNode; + private final BSPTree startNode; /** Node whose intersection with current node defines end point. */ - private final BSPTree endNode; + private final BSPTree endNode; /** Indicator for completely processed edge. */ private boolean processed; @@ -54,9 +54,9 @@ class EdgeWithNodeInfo extends Edge { */ EdgeWithNodeInfo(final Vertex start, final Vertex end, final double length, final Circle circle, - final BSPTree node, - final BSPTree startNode, - final BSPTree endNode) { + final BSPTree node, + final BSPTree startNode, + final BSPTree endNode) { super(start, end, length, circle); this.node = node; this.startNode = startNode; @@ -77,7 +77,7 @@ public static boolean areNaturalFollowers(final EdgeWithNodeInfo previous, final next.getStart().getLocation().getVector()) > 0.0; } - /** Check if two edges result from a single edged having split by a circle. + /** Check if two edges result from a single edged having been split by a circle. * @param previous candidate previous edge * @param next candidate next edge * @return true if {@code edge} is a natural follower for instance diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/spherical/twod/EdgesWithNodeInfoBuilder.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/spherical/twod/EdgesWithNodeInfoBuilder.java index e904aedf8..bba73474f 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/spherical/twod/EdgesWithNodeInfoBuilder.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/spherical/twod/EdgesWithNodeInfoBuilder.java @@ -33,7 +33,7 @@ /** Visitor building edges. * @since 1.4 */ -class EdgesWithNodeInfoBuilder implements BSPTreeVisitor { +class EdgesWithNodeInfoBuilder implements BSPTreeVisitor { /** Tolerance for close nodes connection. */ private final double tolerance; @@ -51,16 +51,16 @@ class EdgesWithNodeInfoBuilder implements BSPTreeVisitor { /** {@inheritDoc} */ @Override - public Order visitOrder(final BSPTree node) { + public Order visitOrder(final BSPTree node) { return Order.MINUS_SUB_PLUS; } /** {@inheritDoc} */ @Override - public void visitInternalNode(final BSPTree node) { + public void visitInternalNode(final BSPTree node) { @SuppressWarnings("unchecked") - final BoundaryAttribute attribute = (BoundaryAttribute) node.getAttribute(); - final Iterable> splitters = attribute.getSplitters(); + final BoundaryAttribute attribute = (BoundaryAttribute) node.getAttribute(); + final Iterable> splitters = attribute.getSplitters(); if (attribute.getPlusOutside() != null) { addContribution(attribute.getPlusOutside(), node, splitters, false); } @@ -71,7 +71,7 @@ public void visitInternalNode(final BSPTree node) { /** {@inheritDoc} */ @Override - public void visitLeafNode(final BSPTree node) { + public void visitLeafNode(final BSPTree node) { } /** Add the contribution of a boundary edge. @@ -80,11 +80,11 @@ public void visitLeafNode(final BSPTree node) { * @param splitters splitters for the boundary facet * @param reversed if true, the facet has the inside on its plus side */ - private void addContribution(final SubHyperplane sub, final BSPTree node, - final Iterable> splitters, + private void addContribution(final SubHyperplane sub, final BSPTree node, + final Iterable> splitters, final boolean reversed) { - final AbstractSubHyperplane absSub = - (AbstractSubHyperplane) sub; + final AbstractSubHyperplane absSub = + (AbstractSubHyperplane) sub; final Circle circle = (Circle) sub.getHyperplane(); final List arcs = ((ArcsSet) absSub.getRemainingRegion()).asList(); for (final Arc a : arcs) { @@ -94,8 +94,8 @@ private void addContribution(final SubHyperplane sub, final BSPTree startN = selectClosest(startS.getLocation(), splitters); - final BSPTree endN = selectClosest(endS.getLocation(), splitters); + final BSPTree startN = selectClosest(startS.getLocation(), splitters); + final BSPTree endN = selectClosest(endS.getLocation(), splitters); if (reversed) { edges.add(new EdgeWithNodeInfo(endS, startS, a.getSize(), circle.getReverse(), @@ -113,16 +113,16 @@ private void addContribution(final SubHyperplane sub, final BSPTree selectClosest(final S2Point point, final Iterable> candidates) { + private BSPTree selectClosest(final S2Point point, final Iterable> candidates) { if (point == null) { return null; } - BSPTree selected = null; + BSPTree selected = null; double min = Double.POSITIVE_INFINITY; - for (final BSPTree node : candidates) { + for (final BSPTree node : candidates) { final double distance = FastMath.abs(node.getCut().getHyperplane().getOffset(point)); if (distance < min) { selected = node; diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/spherical/twod/PropertiesComputer.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/spherical/twod/PropertiesComputer.java index 356200711..b117d835a 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/spherical/twod/PropertiesComputer.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/spherical/twod/PropertiesComputer.java @@ -33,7 +33,7 @@ /** Visitor computing geometrical properties. */ -class PropertiesComputer implements BSPTreeVisitor { +class PropertiesComputer implements BSPTreeVisitor { /** Tolerance below which points are consider to be identical. */ private final double tolerance; @@ -59,19 +59,19 @@ class PropertiesComputer implements BSPTreeVisitor { /** {@inheritDoc} */ @Override - public Order visitOrder(final BSPTree node) { + public Order visitOrder(final BSPTree node) { return Order.MINUS_SUB_PLUS; } /** {@inheritDoc} */ @Override - public void visitInternalNode(final BSPTree node) { + public void visitInternalNode(final BSPTree node) { // nothing to do here } /** {@inheritDoc} */ @Override - public void visitLeafNode(final BSPTree node) { + public void visitLeafNode(final BSPTree node) { if ((Boolean) node.getAttribute()) { // transform this inside leaf cell into a simple convex polygon diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/spherical/twod/Sphere2D.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/spherical/twod/Sphere2D.java index 6860835a0..aed3f0184 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/spherical/twod/Sphere2D.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/spherical/twod/Sphere2D.java @@ -71,7 +71,7 @@ public static Sphere2D getInstance() { */ public static void checkTolerance(final double tolerance) throws MathIllegalArgumentException { - if (tolerance < Sphere1D.SMALLEST_TOLERANCE) { + if (tolerance < SMALLEST_TOLERANCE) { throw new MathIllegalArgumentException(LocalizedGeometryFormats.TOO_SMALL_TOLERANCE, tolerance, "Sphere2D.SMALLEST_TOLERANCE", SMALLEST_TOLERANCE); } diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/spherical/twod/SphericalPolygonsSet.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/spherical/twod/SphericalPolygonsSet.java index 4c8974f05..a14e10f51 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/spherical/twod/SphericalPolygonsSet.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/spherical/twod/SphericalPolygonsSet.java @@ -32,6 +32,7 @@ import org.hipparchus.exception.MathIllegalArgumentException; import org.hipparchus.exception.MathIllegalStateException; import org.hipparchus.geometry.LocalizedGeometryFormats; +import org.hipparchus.geometry.Point; import org.hipparchus.geometry.enclosing.EnclosingBall; import org.hipparchus.geometry.enclosing.WelzlEncloser; import org.hipparchus.geometry.euclidean.threed.Euclidean3D; @@ -45,6 +46,7 @@ import org.hipparchus.geometry.partitioning.RegionFactory; import org.hipparchus.geometry.partitioning.SubHyperplane; import org.hipparchus.geometry.spherical.oned.Arc; +import org.hipparchus.geometry.spherical.oned.S1Point; import org.hipparchus.geometry.spherical.oned.Sphere1D; import org.hipparchus.util.FastMath; import org.hipparchus.util.MathUtils; @@ -52,14 +54,15 @@ /** This class represents a region on the 2-sphere: a set of spherical polygons. */ -public class SphericalPolygonsSet extends AbstractRegion { +public class SphericalPolygonsSet extends AbstractRegion { /** Boundary defined as an array of closed loops start vertices. */ private List loops; /** Build a polygons set representing the whole real 2-sphere. * @param tolerance below which points are consider to be identical - * @exception MathIllegalArgumentException if tolerance is smaller than {@link Sphere1D#SMALLEST_TOLERANCE} + * @exception MathIllegalArgumentException if tolerance is smaller than {@link + * Sphere2D#SMALLEST_TOLERANCE} */ public SphericalPolygonsSet(final double tolerance) throws MathIllegalArgumentException { super(tolerance); @@ -69,14 +72,14 @@ public SphericalPolygonsSet(final double tolerance) throws MathIllegalArgumentEx /** Build a polygons set representing a hemisphere. * @param pole pole of the hemisphere (the pole is in the inside half) * @param tolerance below which points are consider to be identical - * @exception MathIllegalArgumentException if tolerance is smaller than {@link Sphere1D#SMALLEST_TOLERANCE} + * @exception MathIllegalArgumentException if tolerance is smaller than {@link Sphere2D#SMALLEST_TOLERANCE} */ public SphericalPolygonsSet(final Vector3D pole, final double tolerance) throws MathIllegalArgumentException { - super(new BSPTree(new Circle(pole, tolerance).wholeHyperplane(), - new BSPTree(Boolean.FALSE), - new BSPTree(Boolean.TRUE), - null), + super(new BSPTree<>(new Circle(pole, tolerance).wholeHyperplane(), + new BSPTree<>(Boolean.FALSE), + new BSPTree<>(Boolean.TRUE), + null), tolerance); Sphere2D.checkTolerance(tolerance); } @@ -87,7 +90,7 @@ public SphericalPolygonsSet(final Vector3D pole, final double tolerance) * @param outsideRadius distance of the vertices to the center * @param n number of sides of the polygon * @param tolerance below which points are consider to be identical - * @exception MathIllegalArgumentException if tolerance is smaller than {@link Sphere1D#SMALLEST_TOLERANCE} + * @exception MathIllegalArgumentException if tolerance is smaller than {@link Sphere2D#SMALLEST_TOLERANCE} */ public SphericalPolygonsSet(final Vector3D center, final Vector3D meridian, final double outsideRadius, final int n, @@ -105,9 +108,9 @@ public SphericalPolygonsSet(final Vector3D center, final Vector3D meridian, * {@code Boolean.TRUE} and {@code Boolean.FALSE}

* @param tree inside/outside BSP tree representing the region * @param tolerance below which points are consider to be identical - * @exception MathIllegalArgumentException if tolerance is smaller than {@link Sphere1D#SMALLEST_TOLERANCE} + * @exception MathIllegalArgumentException if tolerance is smaller than {@link Sphere2D#SMALLEST_TOLERANCE} */ - public SphericalPolygonsSet(final BSPTree tree, final double tolerance) + public SphericalPolygonsSet(final BSPTree tree, final double tolerance) throws MathIllegalArgumentException { super(tree, tolerance); Sphere2D.checkTolerance(tolerance); @@ -133,9 +136,9 @@ public SphericalPolygonsSet(final BSPTree tree, final double tolerance * @param boundary collection of boundary elements, as a * collection of {@link SubHyperplane SubHyperplane} objects * @param tolerance below which points are consider to be identical - * @exception MathIllegalArgumentException if tolerance is smaller than {@link Sphere1D#SMALLEST_TOLERANCE} + * @exception MathIllegalArgumentException if tolerance is smaller than {@link Sphere2D#SMALLEST_TOLERANCE} */ - public SphericalPolygonsSet(final Collection> boundary, final double tolerance) + public SphericalPolygonsSet(final Collection> boundary, final double tolerance) throws MathIllegalArgumentException { super(boundary, tolerance); Sphere2D.checkTolerance(tolerance); @@ -161,8 +164,8 @@ public SphericalPolygonsSet(final Collection> boundary, * {@link RegionFactory} instead.

*

The list of {@code vertices} is reduced by selecting a sub-set of vertices * before creating the boundary set. Every point in {@code vertices} will be on the - * {@link #checkPoint(org.hipparchus.geometry.Point) boundary} of the constructed polygon set, but not - * necessarily the center-line of the boundary.

+ * {boundary of the constructed polygon set, but not necessarily the center-line of + * the boundary.

*

* Polygons with thin pikes or dents are inherently difficult to handle because * they involve circles with almost opposite directions at some vertices. Polygons @@ -231,14 +234,14 @@ private static S2Point[] createRegularPolygonVertices(final Vector3D center, fin * @param vertices vertices of the simple loop boundary * @return the BSP tree of the input vertices */ - private static BSPTree verticesToTree(final double hyperplaneThickness, - S2Point ... vertices) { + private static BSPTree verticesToTree(final double hyperplaneThickness, + S2Point ... vertices) { // thin vertices to those that define distinct circles vertices = reduce(hyperplaneThickness, vertices).toArray(new S2Point[0]); final int n = vertices.length; if (n == 0) { // the tree represents the whole space - return new BSPTree(Boolean.TRUE); + return new BSPTree<>(Boolean.TRUE); } // build the vertices @@ -268,8 +271,8 @@ private static BSPTree verticesToTree(final double hyperplaneThickness } // build the tree top-down - final BSPTree tree = new BSPTree<>(); - insertEdges(hyperplaneThickness, tree, edges); + final BSPTree tree = new BSPTree<>(); + insertEdges(tree, edges); return tree; @@ -428,17 +431,14 @@ private static int searchHelper(final IntPredicate predicate, return low - 1; } - /** Recursively build a tree by inserting cut sub-hyperplanes. - * @param hyperplaneThickness tolerance below which points are considered to - * belong to the hyperplane (which is therefore more a slab) - * @param node current tree node (it is a leaf node at the beginning - * of the call) + /** + * Recursively build a tree by inserting cut sub-hyperplanes. + * @param node current tree node (it is a leaf node at the beginning + * of the call) * @param edges list of edges to insert in the cell defined by this node - * (excluding edges not belonging to the cell defined by this node) + * (excluding edges not belonging to the cell defined by this node) */ - private static void insertEdges(final double hyperplaneThickness, - final BSPTree node, - final List edges) { + private static void insertEdges(final BSPTree node, final List edges) { // find an edge with an hyperplane that can be inserted in the node int index = 0; @@ -453,7 +453,7 @@ private static void insertEdges(final double hyperplaneThickness, if (inserted == null) { // no suitable edge was found, the node remains a leaf node // we need to set its inside/outside boolean indicator - final BSPTree parent = node.getParent(); + final BSPTree parent = node.getParent(); if (parent == null || node == parent.getMinus()) { node.setAttribute(Boolean.TRUE); } else { @@ -474,12 +474,12 @@ private static void insertEdges(final double hyperplaneThickness, // recurse through lower levels if (!outsideList.isEmpty()) { - insertEdges(hyperplaneThickness, node.getPlus(), outsideList); + insertEdges(node.getPlus(), outsideList); } else { node.getPlus().setAttribute(Boolean.FALSE); } if (!insideList.isEmpty()) { - insertEdges(hyperplaneThickness, node.getMinus(), insideList); + insertEdges(node.getMinus(), insideList); } else { node.getMinus().setAttribute(Boolean.TRUE); } @@ -488,7 +488,7 @@ private static void insertEdges(final double hyperplaneThickness, /** {@inheritDoc} */ @Override - public SphericalPolygonsSet buildNew(final BSPTree tree) { + public SphericalPolygonsSet buildNew(final BSPTree tree) { return new SphericalPolygonsSet(tree, getTolerance()); } @@ -499,13 +499,13 @@ public SphericalPolygonsSet buildNew(final BSPTree tree) { @Override protected void computeGeometricalProperties() throws MathIllegalStateException { - final BSPTree tree = getTree(true); + final BSPTree tree = getTree(true); if (tree.getCut() == null) { // the instance has a single cell without any boundaries - if (tree.getCut() == null && (Boolean) tree.getAttribute()) { + if ((Boolean) tree.getAttribute()) { // the instance covers the whole space setSize(4 * FastMath.PI); setBarycenter(new S2Point(0, 0)); @@ -569,9 +569,14 @@ public List getBoundaryLoops() throws MathIllegalStateException { pending -= splitEdgeConnections(edges); } if (pending > 0) { - closeVerticesConnections(edges); + pending -= closeVerticesConnections(edges); + } + if (pending > 0) { + // this should not happen + throw new MathIllegalStateException(LocalizedGeometryFormats.OUTLINE_BOUNDARY_LOOP_OPEN); } + // extract the edges loops loops = new ArrayList<>(); for (EdgeWithNodeInfo s = getUnprocessed(edges); s != null; s = getUnprocessed(edges)) { @@ -690,10 +695,6 @@ private void followLoop(final EdgeWithNodeInfo defining) { EdgeWithNodeInfo previous = defining; EdgeWithNodeInfo next = (EdgeWithNodeInfo) defining.getEnd().getOutgoing(); while (next != defining) { - if (next == null) { - // this should not happen - throw new MathIllegalStateException(LocalizedGeometryFormats.OUTLINE_BOUNDARY_LOOP_OPEN); - } next.setProcessed(true); // filter out spurious vertices @@ -715,7 +716,7 @@ private void followLoop(final EdgeWithNodeInfo defining) { *

* This method is intended as a first test to quickly identify points * that are guaranteed to be outside of the region, hence performing a full - * {@link #checkPoint(org.hipparchus.geometry.Vector) checkPoint} + * {@link AbstractRegion#checkPoint(Point)} checkPoint} * only if the point status remains undecided after the quick check. It is * is therefore mostly useful to speed up computation for small polygons with * complex shapes (say a country boundary on Earth), as the spherical cap will @@ -762,25 +763,23 @@ public EnclosingBall getEnclosingCap() { // handle special cases first if (isEmpty()) { - return new EnclosingBall(S2Point.PLUS_K, Double.NEGATIVE_INFINITY); + return new EnclosingBall<>(S2Point.PLUS_K, Double.NEGATIVE_INFINITY); } if (isFull()) { - return new EnclosingBall(S2Point.PLUS_K, Double.POSITIVE_INFINITY); + return new EnclosingBall<>(S2Point.PLUS_K, Double.POSITIVE_INFINITY); } // as the polygons is neither empty nor full, it has some boundaries and cut hyperplanes - final BSPTree root = getTree(false); + final BSPTree root = getTree(false); if (isEmpty(root.getMinus()) && isFull(root.getPlus())) { // the polygon covers an hemisphere, and its boundary is one 2Ï€ long edge final Circle circle = (Circle) root.getCut().getHyperplane(); - return new EnclosingBall(new S2Point(circle.getPole()).negate(), - 0.5 * FastMath.PI); + return new EnclosingBall<>(new S2Point(circle.getPole()).negate(), 0.5 * FastMath.PI); } if (isFull(root.getMinus()) && isEmpty(root.getPlus())) { // the polygon covers an hemisphere, and its boundary is one 2Ï€ long edge final Circle circle = (Circle) root.getCut().getHyperplane(); - return new EnclosingBall(new S2Point(circle.getPole()), - 0.5 * FastMath.PI); + return new EnclosingBall<>(new S2Point(circle.getPole()), 0.5 * FastMath.PI); } // gather some inside points, to be used by the encloser @@ -813,11 +812,11 @@ public EnclosingBall getEnclosingCap() { new EnclosingBall<>(S2Point.PLUS_K, Double.POSITIVE_INFINITY); for (Vector3D outsidePoint : getOutsidePoints()) { final S2Point outsideS2 = new S2Point(outsidePoint); - final BoundaryProjection projection = projectToBoundary(outsideS2); + final BoundaryProjection projection = projectToBoundary(outsideS2); if (FastMath.PI - projection.getOffset() < enclosingS2.getRadius()) { enclosingS2 = new EnclosingBall<>(outsideS2.negate(), FastMath.PI - projection.getOffset(), - (S2Point) projection.getProjected()); + projection.getProjected()); } } return enclosingS2; @@ -848,7 +847,7 @@ private List getInsidePoints() { */ private List getOutsidePoints() { final SphericalPolygonsSet complement = - (SphericalPolygonsSet) new RegionFactory().getComplement(this); + (SphericalPolygonsSet) new RegionFactory().getComplement(this); final PropertiesComputer pc = new PropertiesComputer(getTolerance()); complement.getTree(true).visit(pc); return pc.getConvexCellsInsidePoints(); diff --git a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/spherical/twod/SubCircle.java b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/spherical/twod/SubCircle.java index 245f8d49a..e3c46e0be 100644 --- a/hipparchus-geometry/src/main/java/org/hipparchus/geometry/spherical/twod/SubCircle.java +++ b/hipparchus-geometry/src/main/java/org/hipparchus/geometry/spherical/twod/SubCircle.java @@ -27,32 +27,34 @@ import org.hipparchus.geometry.partitioning.Region; import org.hipparchus.geometry.spherical.oned.Arc; import org.hipparchus.geometry.spherical.oned.ArcsSet; +import org.hipparchus.geometry.spherical.oned.S1Point; import org.hipparchus.geometry.spherical.oned.Sphere1D; import org.hipparchus.util.FastMath; /** This class represents a sub-hyperplane for {@link Circle}. */ -public class SubCircle extends AbstractSubHyperplane { +public class SubCircle extends AbstractSubHyperplane { /** Simple constructor. * @param hyperplane underlying hyperplane * @param remainingRegion remaining region of the hyperplane */ - public SubCircle(final Hyperplane hyperplane, - final Region remainingRegion) { + public SubCircle(final Hyperplane hyperplane, + final Region remainingRegion) { super(hyperplane, remainingRegion); } /** {@inheritDoc} */ @Override - protected AbstractSubHyperplane buildNew(final Hyperplane hyperplane, - final Region remainingRegion) { + protected AbstractSubHyperplane + buildNew(final Hyperplane hyperplane, + final Region remainingRegion) { return new SubCircle(hyperplane, remainingRegion); } /** {@inheritDoc} */ @Override - public SplitSubHyperplane split(final Hyperplane hyperplane) { + public SplitSubHyperplane split(final Hyperplane hyperplane) { final Circle thisCircle = (Circle) getHyperplane(); final Circle otherCircle = (Circle) hyperplane; @@ -60,15 +62,15 @@ public SplitSubHyperplane split(final Hyperplane hyperplane) if (angle < thisCircle.getTolerance() || angle > FastMath.PI - thisCircle.getTolerance()) { // the two circles are aligned or opposite - return new SplitSubHyperplane(null, null); + return new SplitSubHyperplane<>(null, null); } else { // the two circles intersect each other final Arc arc = thisCircle.getInsideArc(otherCircle); final ArcsSet.Split split = ((ArcsSet) getRemainingRegion()).split(arc); final ArcsSet plus = split.getPlus(); final ArcsSet minus = split.getMinus(); - return new SplitSubHyperplane(plus == null ? null : new SubCircle(thisCircle.copySelf(), plus), - minus == null ? null : new SubCircle(thisCircle.copySelf(), minus)); + return new SplitSubHyperplane<>(plus == null ? null : new SubCircle(thisCircle.copySelf(), plus), + minus == null ? null : new SubCircle(thisCircle.copySelf(), minus)); } } diff --git a/hipparchus-geometry/src/site/design/oneD.puml b/hipparchus-geometry/src/site/design/oneD.puml index f2e7a7c9d..fdde2ad56 100644 --- a/hipparchus-geometry/src/site/design/oneD.puml +++ b/hipparchus-geometry/src/site/design/oneD.puml @@ -36,7 +36,7 @@ space with (d-1)-dimensional space end note - interface "Vector" as Vector_S_ { + interface "Vector>" as Vector_S_ { +Space getSpace() +Vector getZero() +double getNorm() @@ -54,9 +54,9 @@ Space <-- Vector_S_ package partitioning #DDEBD8 { - interface "Region" as Region_S_ - interface "Hyperplane" as Hyperplane_S_ - interface "SubHyperplane" as SubHyperplane_S_ + interface "Region>" as Region_S_ + interface "Hyperplane>" as Hyperplane_S_ + interface "SubHyperplane>" as SubHyperplane_S_ } package euclidean #DDEBD8 { diff --git a/hipparchus-geometry/src/site/design/partitioning.puml b/hipparchus-geometry/src/site/design/partitioning.puml index 344bfb0b1..cb940ed79 100644 --- a/hipparchus-geometry/src/site/design/partitioning.puml +++ b/hipparchus-geometry/src/site/design/partitioning.puml @@ -28,7 +28,7 @@ package partitioning #DDEBD8 { - abstract "AbstractSubHyperplane" as AbstractSubHyperplane_S_T_ + abstract "AbstractSubHyperplane, T extends Space, Q extends Point>" as AbstractSubHyperplane_S_T_ note left an abstract sub-hyperplane contains - an hyperplane defined in space S @@ -36,14 +36,14 @@ T being a sub-space of S end note - interface "Hyperplane" as Hyperplane_S_ { + interface "Hyperplane>" as Hyperplane_S_ { +double getOffset(Vector point) +boolean sameOrientationAs(Hyperplane other) +SubHyperplane wholeHyperplane() +Region wholeSpace() } - interface "SubHyperplane" as SubHyperplane_S_ { + interface "SubHyperplane>" as SubHyperplane_S_ { +Hyperplane getHyperplane() +boolean isEmpty() +double getSize() @@ -52,7 +52,7 @@ +SubHyperplane reunite(SubHyperplane other) } - class "BSPTree" as BSPTree_S_ { + class "BSPTree>" as BSPTree_S_ { +boolean insertCut(Hyperplane hyperplane) +void setAttribute(Object attribute) +Object getAttribute() @@ -61,19 +61,19 @@ +BSPTree split(SubHyperplane sub) } - interface "BSPTreeVisitor" as BSPTreeVisitor_S_ { + interface "BSPTreeVisitor>" as BSPTreeVisitor_S_ { +Order visitOrder(BSPTree node) +void visitInternalNode(BSPTree node) +void visitLeafNode(BSPTree node) } - interface "Region" as Region_S_ { + interface "Region>" as Region_S_ { +boolean isEmpty() +boolean contains(Region region) - +Location checkPoint(Vector point) + +Location checkPoint(P point) +double getBoundarySize() +double getSize() - +Vector getBarycenter() + +P getBarycenter() +Side side(Hyperplane hyperplane) +SubHyperplane intersection(SubHyperplane sub) } diff --git a/hipparchus-geometry/src/site/design/threeD.puml b/hipparchus-geometry/src/site/design/threeD.puml index 677d85614..26268f5dd 100644 --- a/hipparchus-geometry/src/site/design/threeD.puml +++ b/hipparchus-geometry/src/site/design/threeD.puml @@ -36,7 +36,7 @@ space with (d-1)-dimensional space end note - interface "Vector" as Vector_S_ { + interface "Vector>" as Vector_S_ { +Space getSpace() +Vector getZero() +double getNorm() @@ -54,9 +54,9 @@ Space <-- Vector_S_ package partitioning #DDEBD8 { - interface "Region" as Region_S_ - interface "Hyperplane" as Hyperplane_S_ - interface "SubHyperplane" as SubHyperplane_S_ + interface "Region>" as Region_S_ + interface "Hyperplane>" as Hyperplane_S_ + interface "SubHyperplane>" as SubHyperplane_S_ } package euclidean #DDEBD8 { diff --git a/hipparchus-geometry/src/site/design/twoD.puml b/hipparchus-geometry/src/site/design/twoD.puml index 76e5e711b..33feb92c0 100644 --- a/hipparchus-geometry/src/site/design/twoD.puml +++ b/hipparchus-geometry/src/site/design/twoD.puml @@ -36,7 +36,7 @@ space with (d-1)-dimensional space end note - interface "Vector" as Vector_S_ { + interface "Vector>" as Vector_S_ { +Space getSpace() +Vector getZero() +double getNorm() @@ -54,9 +54,9 @@ Space <-- Vector_S_ package partitioning #DDEBD8 { - interface "Region" as Region_S_ - interface "Hyperplane" as Hyperplane_S_ - interface "SubHyperplane" as SubHyperplane_S_ + interface "Region>" as Region_S_ + interface "Hyperplane>" as Hyperplane_S_ + interface "SubHyperplane>" as SubHyperplane_S_ } package euclidean #DDEBD8 { diff --git a/hipparchus-geometry/src/test/java/org/hipparchus/geometry/euclidean/oned/IntervalsSetTest.java b/hipparchus-geometry/src/test/java/org/hipparchus/geometry/euclidean/oned/IntervalsSetTest.java index 3759bb091..cea9686c3 100644 --- a/hipparchus-geometry/src/test/java/org/hipparchus/geometry/euclidean/oned/IntervalsSetTest.java +++ b/hipparchus-geometry/src/test/java/org/hipparchus/geometry/euclidean/oned/IntervalsSetTest.java @@ -45,7 +45,7 @@ void testInterval() { new OrientedPoint(new Vector1D(5.7), true, 1.0e-10).wholeHyperplane()), 1.0e-10); assertEquals(3.4, set.getSize(), 1.0e-10); - assertEquals(4.0, ((Vector1D) set.getBarycenter()).getX(), 1.0e-10); + assertEquals(4.0, set.getBarycenter().getX(), 1.0e-10); assertEquals(Region.Location.BOUNDARY, set.checkPoint(new Vector1D(2.3))); assertEquals(Region.Location.BOUNDARY, set.checkPoint(new Vector1D(5.7))); assertEquals(Region.Location.OUTSIDE, set.checkPoint(new Vector1D(1.2))); @@ -85,7 +85,7 @@ void testInfinite() { assertEquals(9.0, set.getInf(), 1.0e-10); assertTrue(Double.isInfinite(set.getSup())); - set = (IntervalsSet) new RegionFactory().getComplement(set); + set = (IntervalsSet) new RegionFactory().getComplement(set); assertEquals(9.0, set.getSup(), 1.0e-10); assertTrue(Double.isInfinite(set.getInf())); @@ -93,14 +93,14 @@ void testInfinite() { @Test void testMultiple() { - RegionFactory factory = new RegionFactory(); + RegionFactory factory = new RegionFactory<>(); IntervalsSet set = (IntervalsSet) factory.intersection(factory.union(factory.difference(new IntervalsSet(1.0, 6.0, 1.0e-10), new IntervalsSet(3.0, 5.0, 1.0e-10)), new IntervalsSet(9.0, Double.POSITIVE_INFINITY, 1.0e-10)), new IntervalsSet(Double.NEGATIVE_INFINITY, 11.0, 1.0e-10)); assertEquals(5.0, set.getSize(), 1.0e-10); - assertEquals(5.9, ((Vector1D) set.getBarycenter()).getX(), 1.0e-10); + assertEquals(5.9, set.getBarycenter().getX(), 1.0e-10); assertEquals(Region.Location.OUTSIDE, set.checkPoint(new Vector1D(0.0))); assertEquals(Region.Location.OUTSIDE, set.checkPoint(new Vector1D(4.0))); assertEquals(Region.Location.OUTSIDE, set.checkPoint(new Vector1D(8.0))); @@ -128,7 +128,7 @@ void testMultiple() { void testSinglePoint() { IntervalsSet set = new IntervalsSet(1.0, 1.0, 1.0e-10); assertEquals(0.0, set.getSize(), Precision.SAFE_MIN); - assertEquals(1.0, ((Vector1D) set.getBarycenter()).getX(), Precision.EPSILON); + assertEquals(1.0, set.getBarycenter().getX(), Precision.EPSILON); try { set.iterator().remove(); fail("an exception should have been thrown"); @@ -201,7 +201,7 @@ private void doTestShuffledTree(final double a0, final double a1, assertEquals(a2, setB.asList().get(1).getInf(), 1.0e-15); assertEquals(a3, setB.asList().get(1).getSup(), 1.0e-15); - final IntervalsSet intersection = (IntervalsSet) new RegionFactory().intersection(setA, setB); + final IntervalsSet intersection = (IntervalsSet) new RegionFactory().intersection(setA, setB); assertEquals((a1 - a0) + (a3 - a2), intersection.getSize(), 1.0e-10); assertEquals(2, intersection.asList().size()); assertEquals(a0, intersection.asList().get(0).getInf(), 1.0e-15); diff --git a/hipparchus-geometry/src/test/java/org/hipparchus/geometry/euclidean/threed/OutlineExtractorTest.java b/hipparchus-geometry/src/test/java/org/hipparchus/geometry/euclidean/threed/OutlineExtractorTest.java index 8e1cb17a4..371aa7bcb 100644 --- a/hipparchus-geometry/src/test/java/org/hipparchus/geometry/euclidean/threed/OutlineExtractorTest.java +++ b/hipparchus-geometry/src/test/java/org/hipparchus/geometry/euclidean/threed/OutlineExtractorTest.java @@ -82,7 +82,7 @@ void testHolesInFacet() { PolyhedronsSet tubeAlongX = new PolyhedronsSet(-2.0, 2.0, -0.5, 0.5, -0.5, 0.5, tolerance); PolyhedronsSet tubeAlongY = new PolyhedronsSet(-0.5, 0.5, -2.0, 2.0, -0.5, 0.5, tolerance); PolyhedronsSet tubeAlongZ = new PolyhedronsSet(-0.5, 0.5, -0.5, 0.5, -2.0, 2.0, tolerance); - RegionFactory factory = new RegionFactory<>(); + RegionFactory factory = new RegionFactory<>(); PolyhedronsSet cubeWithHoles = (PolyhedronsSet) factory.difference(cube, factory.union(tubeAlongX, factory.union(tubeAlongY, tubeAlongZ))); diff --git a/hipparchus-geometry/src/test/java/org/hipparchus/geometry/euclidean/threed/PolyhedronsSetTest.java b/hipparchus-geometry/src/test/java/org/hipparchus/geometry/euclidean/threed/PolyhedronsSetTest.java index 9d31598dc..06a74da4b 100644 --- a/hipparchus-geometry/src/test/java/org/hipparchus/geometry/euclidean/threed/PolyhedronsSetTest.java +++ b/hipparchus-geometry/src/test/java/org/hipparchus/geometry/euclidean/threed/PolyhedronsSetTest.java @@ -26,7 +26,6 @@ import org.hipparchus.exception.MathIllegalArgumentException; import org.hipparchus.exception.MathRuntimeException; import org.hipparchus.geometry.LocalizedGeometryFormats; -import org.hipparchus.geometry.Vector; import org.hipparchus.geometry.euclidean.twod.Euclidean2D; import org.hipparchus.geometry.euclidean.twod.PolygonsSet; import org.hipparchus.geometry.euclidean.twod.SubLine; @@ -48,6 +47,7 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; +import java.nio.charset.StandardCharsets; import java.text.ParseException; import java.util.ArrayList; import java.util.Arrays; @@ -65,7 +65,7 @@ void testBox() { PolyhedronsSet tree = new PolyhedronsSet(0, 1, 0, 1, 0, 1, 1.0e-10); assertEquals(1.0, tree.getSize(), 1.0e-10); assertEquals(6.0, tree.getBoundarySize(), 1.0e-10); - Vector3D barycenter = (Vector3D) tree.getBarycenter(); + Vector3D barycenter = tree.getBarycenter(); assertEquals(0.5, barycenter.getX(), 1.0e-10); assertEquals(0.5, barycenter.getY(), 1.0e-10); assertEquals(0.5, barycenter.getZ(), 1.0e-10); @@ -115,7 +115,7 @@ void testBRepExtractor() { @Test void testEmptyBRepIfEmpty() { - PolyhedronsSet empty = (PolyhedronsSet) new RegionFactory().getComplement(new PolyhedronsSet(1.0e-10)); + PolyhedronsSet empty = (PolyhedronsSet) new RegionFactory().getComplement(new PolyhedronsSet(1.0e-10)); assertTrue(empty.isEmpty()); assertEquals(0.0, empty.getSize(), 1.0e-10); PolyhedronsSet.BRep brep = empty.getBRep(); @@ -125,7 +125,7 @@ void testEmptyBRepIfEmpty() { @Test void testNoBRepHalfSpace() { - BSPTree bsp = new BSPTree<>(); + BSPTree bsp = new BSPTree<>(); bsp.insertCut(new Plane(Vector3D.PLUS_K, 1.0e-10)); bsp.getPlus().setAttribute(Boolean.FALSE); bsp.getMinus().setAttribute(Boolean.TRUE); @@ -141,7 +141,7 @@ void testNoBRepHalfSpace() { @Test void testNoBRepUnboundedOctant() { - BSPTree bsp = new BSPTree<>(); + BSPTree bsp = new BSPTree<>(); bsp.insertCut(new Plane(Vector3D.PLUS_K, 1.0e-10)); bsp.getPlus().setAttribute(Boolean.FALSE); bsp.getMinus().insertCut(new Plane(Vector3D.PLUS_I, 1.0e-10)); @@ -166,7 +166,7 @@ void testNoBRepHolesInFacet() { PolyhedronsSet tubeAlongX = new PolyhedronsSet(-2.0, 2.0, -0.5, 0.5, -0.5, 0.5, tolerance); PolyhedronsSet tubeAlongY = new PolyhedronsSet(-0.5, 0.5, -2.0, 2.0, -0.5, 0.5, tolerance); PolyhedronsSet tubeAlongZ = new PolyhedronsSet(-0.5, 0.5, -0.5, 0.5, -2.0, 2.0, tolerance); - RegionFactory factory = new RegionFactory<>(); + RegionFactory factory = new RegionFactory<>(); PolyhedronsSet cubeWithHoles = (PolyhedronsSet) factory.difference(cube, factory.union(tubeAlongX, factory.union(tubeAlongY, tubeAlongZ))); @@ -186,14 +186,14 @@ void testTetrahedron() throws MathRuntimeException { Vector3D vertex3 = new Vector3D(2, 3, 3); Vector3D vertex4 = new Vector3D(1, 3, 4); PolyhedronsSet tree = - (PolyhedronsSet) new RegionFactory().buildConvex( + (PolyhedronsSet) new RegionFactory().buildConvex( new Plane(vertex3, vertex2, vertex1, 1.0e-10), new Plane(vertex2, vertex3, vertex4, 1.0e-10), new Plane(vertex4, vertex3, vertex1, 1.0e-10), new Plane(vertex1, vertex2, vertex4, 1.0e-10)); assertEquals(1.0 / 3.0, tree.getSize(), 1.0e-10); assertEquals(2.0 * FastMath.sqrt(3.0), tree.getBoundarySize(), 1.0e-10); - Vector3D barycenter = (Vector3D) tree.getBarycenter(); + Vector3D barycenter = tree.getBarycenter(); assertEquals(1.5, barycenter.getX(), 1.0e-10); assertEquals(2.5, barycenter.getY(), 1.0e-10); assertEquals(3.5, barycenter.getZ(), 1.0e-10); @@ -214,31 +214,28 @@ void testTetrahedron() throws MathRuntimeException { } @Test - void testIsometry() throws MathRuntimeException, MathIllegalArgumentException { + void testIsometry() throws MathRuntimeException { Vector3D vertex1 = new Vector3D(1.1, 2.2, 3.3); Vector3D vertex2 = new Vector3D(2.0, 2.4, 4.2); Vector3D vertex3 = new Vector3D(2.8, 3.3, 3.7); Vector3D vertex4 = new Vector3D(1.0, 3.6, 4.5); PolyhedronsSet tree = - (PolyhedronsSet) new RegionFactory().buildConvex( + (PolyhedronsSet) new RegionFactory().buildConvex( new Plane(vertex3, vertex2, vertex1, 1.0e-10), new Plane(vertex2, vertex3, vertex4, 1.0e-10), new Plane(vertex4, vertex3, vertex1, 1.0e-10), new Plane(vertex1, vertex2, vertex4, 1.0e-10)); - Vector3D barycenter = (Vector3D) tree.getBarycenter(); + Vector3D barycenter = tree.getBarycenter(); Vector3D s = new Vector3D(10.2, 4.3, -6.7); Vector3D c = new Vector3D(-0.2, 2.1, -3.2); Rotation r = new Rotation(new Vector3D(6.2, -4.4, 2.1), 0.12, RotationConvention.VECTOR_OPERATOR); tree = tree.rotate(c, r).translate(s); - Vector3D newB = - new Vector3D(1.0, s, - 1.0, c, - 1.0, r.applyTo(barycenter.subtract(c))); - assertEquals(0.0, - newB.subtract((Vector) tree.getBarycenter()).getNorm(), - 1.0e-10); + Vector3D newB = new Vector3D(1.0, s, + 1.0, c, + 1.0, r.applyTo(barycenter.subtract(c))); + assertEquals(0.0, newB.subtract(tree.getBarycenter()).getNorm(), 1.0e-10); final Vector3D[] expectedV = new Vector3D[] { new Vector3D(1.0, s, @@ -254,16 +251,16 @@ void testIsometry() throws MathRuntimeException, MathIllegalArgumentException { 1.0, c, 1.0, r.applyTo(vertex4.subtract(c))) }; - tree.getTree(true).visit(new BSPTreeVisitor() { + tree.getTree(true).visit(new BSPTreeVisitor() { - public Order visitOrder(BSPTree node) { + public Order visitOrder(BSPTree node) { return Order.MINUS_SUB_PLUS; } - public void visitInternalNode(BSPTree node) { + public void visitInternalNode(BSPTree node) { @SuppressWarnings("unchecked") - BoundaryAttribute attribute = - (BoundaryAttribute) node.getAttribute(); + BoundaryAttribute attribute = + (BoundaryAttribute) node.getAttribute(); if (attribute.getPlusOutside() != null) { checkFacet((SubPlane) attribute.getPlusOutside()); } @@ -272,7 +269,7 @@ public void visitInternalNode(BSPTree node) { } } - public void visitLeafNode(BSPTree node) { + public void visitLeafNode(BSPTree node) { } private void checkFacet(SubPlane facet) { @@ -283,8 +280,8 @@ private void checkFacet(SubPlane facet) { for (int i = 0; i < vertices[0].length; ++i) { Vector3D v = plane.toSpace(vertices[0][i]); double d = Double.POSITIVE_INFINITY; - for (int k = 0; k < expectedV.length; ++k) { - d = FastMath.min(d, v.subtract(expectedV[k]).getNorm()); + for (final Vector3D u : expectedV) { + d = FastMath.min(d, v.subtract(u).getNorm()); } assertEquals(0, d, 1.0e-10); } @@ -303,7 +300,7 @@ void testBuildBox() { double l = 1.0; PolyhedronsSet tree = new PolyhedronsSet(x - l, x + l, y - w, y + w, z - w, z + w, 1.0e-10); - Vector3D barycenter = (Vector3D) tree.getBarycenter(); + Vector3D barycenter = tree.getBarycenter(); assertEquals(x, barycenter.getX(), 1.0e-10); assertEquals(y, barycenter.getY(), 1.0e-10); assertEquals(z, barycenter.getZ(), 1.0e-10); @@ -325,9 +322,9 @@ void testCross() { new PolyhedronsSet(x - w, x + w, y - l, y + l, z - w, z + w, 1.0e-10); PolyhedronsSet zBeam = new PolyhedronsSet(x - w, x + w, y - w, y + w, z - l, z + l, 1.0e-10); - RegionFactory factory = new RegionFactory(); + RegionFactory factory = new RegionFactory<>(); PolyhedronsSet tree = (PolyhedronsSet) factory.union(xBeam, factory.union(yBeam, zBeam)); - Vector3D barycenter = (Vector3D) tree.getBarycenter(); + Vector3D barycenter = tree.getBarycenter(); assertEquals(x, barycenter.getX(), 1.0e-10); assertEquals(y, barycenter.getY(), 1.0e-10); @@ -355,7 +352,7 @@ void testIssue780() throws MathRuntimeException { 1, 5, 6, 1, 6, 2, 2, 6, 7, 2, 7, 3, 4, 0, 3, 4, 3, 7}; - ArrayList> subHyperplaneList = new ArrayList>(); + ArrayList> subHyperplaneList = new ArrayList<>(); for (int idx = 0; idx < indices.length; idx += 3) { int idxA = indices[idx] * 3; int idxB = indices[idx + 1] * 3; @@ -365,19 +362,17 @@ void testIssue780() throws MathRuntimeException { Vector3D v_3 = new Vector3D(coords[idxC], coords[idxC + 1], coords[idxC + 2]); Vector3D[] vertices = {v_1, v_2, v_3}; Plane polyPlane = new Plane(v_1, v_2, v_3, 1.0e-10); - ArrayList> lines = new ArrayList>(); + ArrayList> lines = new ArrayList<>(); Vector2D[] projPts = new Vector2D[vertices.length]; for (int ptIdx = 0; ptIdx < projPts.length; ptIdx++) { projPts[ptIdx] = polyPlane.toSubSpace(vertices[ptIdx]); } - SubLine lineInPlane = null; for (int ptIdx = 0; ptIdx < projPts.length; ptIdx++) { - lineInPlane = new SubLine(projPts[ptIdx], projPts[(ptIdx + 1) % projPts.length], 1.0e-10); - lines.add(lineInPlane); + lines.add(new SubLine(projPts[ptIdx], projPts[(ptIdx + 1) % projPts.length], 1.0e-10)); } - Region polyRegion = new PolygonsSet(lines, 1.0e-10); + Region polyRegion = new PolygonsSet(lines, 1.0e-10); SubPlane polygon = new SubPlane(polyPlane, polyRegion); subHyperplaneList.add(polygon); } @@ -398,7 +393,7 @@ void testWrongUsage() { // the following is a wrong usage of the constructor. // as explained in the javadoc, the failure is NOT detected at construction // time but occurs later on - PolyhedronsSet ps = new PolyhedronsSet(new BSPTree(), 1.0e-10); + PolyhedronsSet ps = new PolyhedronsSet(new BSPTree<>(), 1.0e-10); assertNotNull(ps); try { ps.checkPoint(Vector3D.ZERO); @@ -445,7 +440,7 @@ void testDumpParse() throws IOException, ParseException { PolyhedronsSet parsed = RegionParser.parsePolyhedronsSet(dump); assertEquals(8.0, parsed.getSize(), 1.0e-10); assertEquals(24.0, parsed.getBoundarySize(), 1.0e-10); - assertTrue(new RegionFactory().difference(polyset, parsed).isEmpty()); + assertTrue(new RegionFactory().difference(polyset, parsed).isEmpty()); } @Test @@ -459,27 +454,27 @@ void testConnectedFacets() throws IOException, ParseException { } @Test - void testTooClose() throws IOException, ParseException { + void testTooClose() { checkError("pentomino-N-too-close.ply", LocalizedGeometryFormats.CLOSE_VERTICES); } @Test - void testHole() throws IOException, ParseException { + void testHole() { checkError("pentomino-N-hole.ply", LocalizedGeometryFormats.EDGE_CONNECTED_TO_ONE_FACET); } @Test - void testNonPlanar() throws IOException, ParseException { + void testNonPlanar() { checkError("pentomino-N-out-of-plane.ply", LocalizedGeometryFormats.OUT_OF_PLANE); } @Test - void testOrientation() throws IOException, ParseException { + void testOrientation() { checkError("pentomino-N-bad-orientation.ply", LocalizedGeometryFormats.FACET_ORIENTATION_MISMATCH); } @Test - void testFacet2Vertices() throws IOException, ParseException { + void testFacet2Vertices() { checkError(Arrays.asList(Vector3D.ZERO, Vector3D.PLUS_I, Vector3D.PLUS_J, Vector3D.PLUS_K), Arrays.asList(new int[] { 0, 1, 2 }, new int[] {2, 3}), LocalizedCoreFormats.WRONG_NUMBER_OF_POINTS); @@ -491,10 +486,8 @@ private void checkError(final String resourceName, final Localizable expected) { PLYParser parser = new PLYParser(stream); stream.close(); checkError(parser.getVertices(), parser.getFaces(), expected); - } catch (IOException ioe) { - fail(ioe.getLocalizedMessage()); - } catch (ParseException pe) { - fail(pe.getLocalizedMessage()); + } catch (IOException | ParseException e) { + fail(e.getLocalizedMessage()); } } @@ -555,7 +548,7 @@ void testFirstIntersectionLinesPassThroughBoundaries() { void testIssue1211() throws IOException, ParseException { PolyhedronsSet polyset = RegionParser.parsePolyhedronsSet(loadTestData("issue-1211.bsp")); - RandomGenerator random = new Well1024a(0xb97c9d1ade21e40al); + RandomGenerator random = new Well1024a(0xb97c9d1ade21e40aL); int nrays = 1000; for (int i = 0; i < nrays; i++) { Vector3D origin = Vector3D.ZERO; @@ -563,7 +556,7 @@ void testIssue1211() throws IOException, ParseException { 2 * random.nextDouble() - 1, 2 * random.nextDouble() - 1).normalize(); Line line = new Line(origin, origin.add(direction), polyset.getTolerance()); - SubHyperplane plane = polyset.firstIntersection(origin, line); + SubHyperplane plane = polyset.firstIntersection(origin, line); if (plane != null) { Vector3D intersectionPoint = ((Plane)plane.getHyperplane()).intersection(line); double dotProduct = direction.dotProduct(intersectionPoint.subtract(origin)); @@ -575,7 +568,7 @@ void testIssue1211() throws IOException, ParseException { private String loadTestData(final String resourceName) throws IOException { InputStream stream = getClass().getResourceAsStream(resourceName); - Reader reader = new InputStreamReader(stream, "UTF-8"); + Reader reader = new InputStreamReader(stream, StandardCharsets.UTF_8); StringBuilder builder = new StringBuilder(); for (int c = reader.read(); c >= 0; c = reader.read()) { builder.append((char) c); @@ -584,8 +577,8 @@ private String loadTestData(final String resourceName) } private void checkPoints(Region.Location expected, PolyhedronsSet tree, Vector3D[] points) { - for (int i = 0; i < points.length; ++i) { - assertEquals(expected, tree.checkPoint(points[i])); + for (final Vector3D point : points) { + assertEquals(expected, tree.checkPoint(point)); } } diff --git a/hipparchus-geometry/src/test/java/org/hipparchus/geometry/euclidean/threed/SubLineTest.java b/hipparchus-geometry/src/test/java/org/hipparchus/geometry/euclidean/threed/SubLineTest.java index 907b73ac8..9187519cc 100644 --- a/hipparchus-geometry/src/test/java/org/hipparchus/geometry/euclidean/threed/SubLineTest.java +++ b/hipparchus-geometry/src/test/java/org/hipparchus/geometry/euclidean/threed/SubLineTest.java @@ -24,6 +24,7 @@ import org.hipparchus.exception.MathIllegalArgumentException; import org.hipparchus.geometry.euclidean.oned.Euclidean1D; import org.hipparchus.geometry.euclidean.oned.IntervalsSet; +import org.hipparchus.geometry.euclidean.oned.Vector1D; import org.hipparchus.geometry.partitioning.RegionFactory; import org.junit.jupiter.api.Test; @@ -69,7 +70,7 @@ void testNoEndPoints() throws MathIllegalArgumentException { @Test void testNoSegments() throws MathIllegalArgumentException { SubLine empty = new SubLine(new Line(new Vector3D(-1, -7, 2), new Vector3D(7, -1, 0), 1.0e-10), - (IntervalsSet) new RegionFactory().getComplement(new IntervalsSet(1.0e-10))); + (IntervalsSet) new RegionFactory().getComplement(new IntervalsSet(1.0e-10))); List segments = empty.getSegments(); assertEquals(0, segments.size()); } @@ -77,8 +78,8 @@ void testNoSegments() throws MathIllegalArgumentException { @Test void testSeveralSegments() throws MathIllegalArgumentException { SubLine twoSubs = new SubLine(new Line(new Vector3D(-1, -7, 2), new Vector3D(7, -1, 0), 1.0e-10), - (IntervalsSet) new RegionFactory().union(new IntervalsSet(1, 2, 1.0e-10), - new IntervalsSet(3, 4, 1.0e-10))); + (IntervalsSet) new RegionFactory(). + union(new IntervalsSet(1, 2, 1.0e-10), new IntervalsSet(3, 4, 1.0e-10))); List segments = twoSubs.getSegments(); assertEquals(2, segments.size()); } diff --git a/hipparchus-geometry/src/test/java/org/hipparchus/geometry/euclidean/twod/LineTest.java b/hipparchus-geometry/src/test/java/org/hipparchus/geometry/euclidean/twod/LineTest.java index 940c909cb..b3e09b5f5 100644 --- a/hipparchus-geometry/src/test/java/org/hipparchus/geometry/euclidean/twod/LineTest.java +++ b/hipparchus-geometry/src/test/java/org/hipparchus/geometry/euclidean/twod/LineTest.java @@ -22,7 +22,6 @@ package org.hipparchus.geometry.euclidean.twod; import org.hipparchus.exception.MathIllegalArgumentException; -import org.hipparchus.geometry.Point; import org.hipparchus.geometry.euclidean.oned.Euclidean1D; import org.hipparchus.geometry.euclidean.oned.Vector1D; import org.hipparchus.geometry.partitioning.Transform; @@ -79,12 +78,12 @@ void testDistance() { void testPointAt() { Line l = new Line(new Vector2D(2, 1), new Vector2D(-2, -2), 1.0e-10); for (double a = -2.0; a < 2.0; a += 0.2) { - Point pA = new Vector1D(a); - Point point = l.toSpace(pA); + Vector1D pA = new Vector1D(a); + Vector2D point = l.toSpace(pA); assertEquals(a, (l.toSubSpace(point)).getX(), 1.0e-10); assertEquals(0.0, l.getOffset(point), 1.0e-10); for (double o = -2.0; o < 2.0; o += 0.2) { - point = l.getPointAt((Vector1D) pA, o); + point = l.getPointAt(pA, o); assertEquals(a, (l.toSubSpace(point)).getX(), 1.0e-10); assertEquals(o, l.getOffset(point), 1.0e-10); } @@ -114,14 +113,14 @@ void testParallel() { void testTransform() throws MathIllegalArgumentException { Line l1 = new Line(new Vector2D(1.0 ,1.0), new Vector2D(4.0 ,1.0), 1.0e-10); - Transform t1 = + Transform t1 = Line.getTransform(0.0, 0.5, -1.0, 0.0, 1.0, 1.5); assertEquals(0.5 * FastMath.PI, ((Line) t1.apply(l1)).getAngle(), 1.0e-10); Line l2 = new Line(new Vector2D(0.0, 0.0), new Vector2D(1.0, 1.0), 1.0e-10); - Transform t2 = + Transform t2 = Line.getTransform(0.0, 0.5, -1.0, 0.0, 1.0, 1.5); assertEquals(FastMath.atan2(1.0, -2.0), ((Line) t2.apply(l2)).getAngle(), diff --git a/hipparchus-geometry/src/test/java/org/hipparchus/geometry/euclidean/twod/PolygonsSetTest.java b/hipparchus-geometry/src/test/java/org/hipparchus/geometry/euclidean/twod/PolygonsSetTest.java index 3d85410f6..620369fa6 100644 --- a/hipparchus-geometry/src/test/java/org/hipparchus/geometry/euclidean/twod/PolygonsSetTest.java +++ b/hipparchus-geometry/src/test/java/org/hipparchus/geometry/euclidean/twod/PolygonsSetTest.java @@ -49,6 +49,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; @@ -105,7 +106,7 @@ void testBox() { @Test void testInfinite() { - PolygonsSet box = new PolygonsSet(new BSPTree(Boolean.TRUE), 1.0e-10); + PolygonsSet box = new PolygonsSet(new BSPTree<>(Boolean.TRUE), 1.0e-10); assertTrue(Double.isInfinite(box.getSize())); } @@ -136,7 +137,7 @@ void testStair() { @Test void testEmpty() { - PolygonsSet empty = (PolygonsSet) new RegionFactory().getComplement(new PolygonsSet(1.0e-10)); + PolygonsSet empty = (PolygonsSet) new RegionFactory().getComplement(new PolygonsSet(1.0e-10)); assertTrue(empty.isEmpty()); assertEquals(0, empty.getVertices().length); assertEquals(0.0, empty.getBoundarySize(), 1.0e-10); @@ -211,9 +212,9 @@ void testHole() { for (double x = -0.999; x < 3.999; x += 0.11) { Vector2D v = new Vector2D(x, x + 0.5); - BoundaryProjection projection = set.projectToBoundary(v); - assertTrue(projection.getOriginal() == v); - Vector2D p = (Vector2D) projection.getProjected(); + BoundaryProjection projection = set.projectToBoundary(v); + assertSame(projection.getOriginal(), v); + Vector2D p = projection.getProjected(); if (x < -0.5) { assertEquals(0.0, p.getX(), 1.0e-10); assertEquals(0.0, p.getY(), 1.0e-10); @@ -381,8 +382,7 @@ void testUnlimitedSubHyperplane() { PolygonsSet set2 = buildSet(vertices2); PolygonsSet set = - (PolygonsSet) new RegionFactory().union(set1.copySelf(), - set2.copySelf()); + (PolygonsSet) new RegionFactory().union(set1.copySelf(), set2.copySelf()); checkVertices(set1.getVertices(), vertices1); checkVertices(set2.getVertices(), vertices2); checkVertices(set.getVertices(), new Vector2D[][] { @@ -419,8 +419,7 @@ void testUnion() { } }; PolygonsSet set2 = buildSet(vertices2); - PolygonsSet set = (PolygonsSet) new RegionFactory().union(set1.copySelf(), - set2.copySelf()); + PolygonsSet set = (PolygonsSet) new RegionFactory().union(set1.copySelf(), set2.copySelf()); checkVertices(set1.getVertices(), vertices1); checkVertices(set2.getVertices(), vertices2); checkVertices(set.getVertices(), new Vector2D[][] { @@ -483,8 +482,7 @@ void testIntersection() { } }; PolygonsSet set2 = buildSet(vertices2); - PolygonsSet set = (PolygonsSet) new RegionFactory().intersection(set1.copySelf(), - set2.copySelf()); + PolygonsSet set = (PolygonsSet) new RegionFactory().intersection(set1.copySelf(), set2.copySelf()); checkVertices(set1.getVertices(), vertices1); checkVertices(set2.getVertices(), vertices2); checkVertices(set.getVertices(), new Vector2D[][] { @@ -532,8 +530,7 @@ void testXor() { } }; PolygonsSet set2 = buildSet(vertices2); - PolygonsSet set = (PolygonsSet) new RegionFactory().xor(set1.copySelf(), - set2.copySelf()); + PolygonsSet set = (PolygonsSet) new RegionFactory().xor(set1.copySelf(), set2.copySelf()); checkVertices(set1.getVertices(), vertices1); checkVertices(set2.getVertices(), vertices2); checkVertices(set.getVertices(), new Vector2D[][] { @@ -603,8 +600,7 @@ void testDifference() { } }; PolygonsSet set2 = buildSet(vertices2); - PolygonsSet set = (PolygonsSet) new RegionFactory().difference(set1.copySelf(), - set2.copySelf()); + PolygonsSet set = (PolygonsSet) new RegionFactory().difference(set1.copySelf(), set2.copySelf()); checkVertices(set1.getVertices(), vertices1); checkVertices(set2.getVertices(), vertices2); checkVertices(set.getVertices(), new Vector2D[][] { @@ -666,7 +662,7 @@ void testEmptyDifference() { } }; PolygonsSet set2 = buildSet(vertices2); - assertTrue(new RegionFactory().difference(set1.copySelf(), set2.copySelf()).isEmpty()); + assertTrue(new RegionFactory().difference(set1.copySelf(), set2.copySelf()).isEmpty()); } @Test @@ -688,17 +684,17 @@ void testChoppedHexagon() { hyp[4] = (SubLine) hyp[4].split(hyp[3].getHyperplane()).getMinus().split(hyp[0].getHyperplane()).getMinus(); hyp[5] = (SubLine) hyp[5].split(hyp[4].getHyperplane()).getMinus().split(hyp[0].getHyperplane()).getMinus(); hyp[6] = (SubLine) hyp[6].split(hyp[3].getHyperplane()).getMinus().split(hyp[1].getHyperplane()).getMinus(); - BSPTree tree = new BSPTree(Boolean.TRUE); + BSPTree tree = new BSPTree<>(Boolean.TRUE); for (int i = hyp.length - 1; i >= 0; --i) { - tree = new BSPTree(hyp[i], new BSPTree(Boolean.FALSE), tree, null); + tree = new BSPTree<>(hyp[i], new BSPTree<>(Boolean.FALSE), tree, null); } PolygonsSet set = new PolygonsSet(tree, 1.0e-10); SubLine splitter = new Line(new Vector2D(-2.0 * sqrt3 / 3.0, 0.0), 9 * pi6, 1.0e-10).wholeHyperplane(); PolygonsSet slice = - new PolygonsSet(new BSPTree(splitter, - set.getTree(false).split(splitter).getPlus(), - new BSPTree(Boolean.FALSE), null), + new PolygonsSet(new BSPTree<>(splitter, + set.getTree(false).split(splitter).getPlus(), + new BSPTree<>(Boolean.FALSE), null), 1.0e-10); assertEquals(Region.Location.OUTSIDE, slice.checkPoint(new Vector2D(0.1, 0.5))); @@ -738,92 +734,92 @@ void testConcentric() { @Test void testBug20040520() { - BSPTree a0 = - new BSPTree(buildSegment(new Vector2D(0.85, -0.05), - new Vector2D(0.90, -0.10)), - new BSPTree(Boolean.FALSE), - new BSPTree(Boolean.TRUE), - null); - BSPTree a1 = - new BSPTree(buildSegment(new Vector2D(0.85, -0.10), - new Vector2D(0.90, -0.10)), - new BSPTree(Boolean.FALSE), a0, null); - BSPTree a2 = - new BSPTree(buildSegment(new Vector2D(0.90, -0.05), - new Vector2D(0.85, -0.05)), - new BSPTree(Boolean.FALSE), a1, null); - BSPTree a3 = - new BSPTree(buildSegment(new Vector2D(0.82, -0.05), - new Vector2D(0.82, -0.08)), - new BSPTree(Boolean.FALSE), - new BSPTree(Boolean.TRUE), - null); - BSPTree a4 = - new BSPTree(buildHalfLine(new Vector2D(0.85, -0.05), - new Vector2D(0.80, -0.05), - false), - new BSPTree(Boolean.FALSE), a3, null); - BSPTree a5 = - new BSPTree(buildSegment(new Vector2D(0.82, -0.08), - new Vector2D(0.82, -0.18)), - new BSPTree(Boolean.FALSE), - new BSPTree(Boolean.TRUE), - null); - BSPTree a6 = - new BSPTree(buildHalfLine(new Vector2D(0.82, -0.18), - new Vector2D(0.85, -0.15), - true), - new BSPTree(Boolean.FALSE), a5, null); - BSPTree a7 = - new BSPTree(buildHalfLine(new Vector2D(0.85, -0.05), - new Vector2D(0.82, -0.08), - false), - a4, a6, null); - BSPTree a8 = - new BSPTree(buildLine(new Vector2D(0.85, -0.25), - new Vector2D(0.85, 0.05)), - a2, a7, null); - BSPTree a9 = - new BSPTree(buildLine(new Vector2D(0.90, 0.05), - new Vector2D(0.90, -0.50)), - a8, new BSPTree(Boolean.FALSE), null); - - BSPTree b0 = - new BSPTree(buildSegment(new Vector2D(0.92, -0.12), - new Vector2D(0.92, -0.08)), - new BSPTree(Boolean.FALSE), new BSPTree(Boolean.TRUE), - null); - BSPTree b1 = - new BSPTree(buildHalfLine(new Vector2D(0.92, -0.08), - new Vector2D(0.90, -0.10), - true), - new BSPTree(Boolean.FALSE), b0, null); - BSPTree b2 = - new BSPTree(buildSegment(new Vector2D(0.92, -0.18), - new Vector2D(0.92, -0.12)), - new BSPTree(Boolean.FALSE), new BSPTree(Boolean.TRUE), - null); - BSPTree b3 = - new BSPTree(buildSegment(new Vector2D(0.85, -0.15), - new Vector2D(0.90, -0.20)), - new BSPTree(Boolean.FALSE), b2, null); - BSPTree b4 = - new BSPTree(buildSegment(new Vector2D(0.95, -0.15), - new Vector2D(0.85, -0.05)), - b1, b3, null); - BSPTree b5 = - new BSPTree(buildHalfLine(new Vector2D(0.85, -0.05), - new Vector2D(0.85, -0.25), - true), - new BSPTree(Boolean.FALSE), b4, null); - BSPTree b6 = - new BSPTree(buildLine(new Vector2D(0.0, -1.10), - new Vector2D(1.0, -0.10)), - new BSPTree(Boolean.FALSE), b5, null); + BSPTree a0 = + new BSPTree<>(buildSegment(new Vector2D(0.85, -0.05), + new Vector2D(0.90, -0.10)), + new BSPTree<>(Boolean.FALSE), + new BSPTree<>(Boolean.TRUE), + null); + BSPTree a1 = + new BSPTree<>(buildSegment(new Vector2D(0.85, -0.10), + new Vector2D(0.90, -0.10)), + new BSPTree<>(Boolean.FALSE), a0, null); + BSPTree a2 = + new BSPTree<>(buildSegment(new Vector2D(0.90, -0.05), + new Vector2D(0.85, -0.05)), + new BSPTree<>(Boolean.FALSE), a1, null); + BSPTree a3 = + new BSPTree<>(buildSegment(new Vector2D(0.82, -0.05), + new Vector2D(0.82, -0.08)), + new BSPTree<>(Boolean.FALSE), + new BSPTree<>(Boolean.TRUE), + null); + BSPTree a4 = + new BSPTree<>(buildHalfLine(new Vector2D(0.85, -0.05), + new Vector2D(0.80, -0.05), + false), + new BSPTree<>(Boolean.FALSE), a3, null); + BSPTree a5 = + new BSPTree<>(buildSegment(new Vector2D(0.82, -0.08), + new Vector2D(0.82, -0.18)), + new BSPTree<>(Boolean.FALSE), + new BSPTree<>(Boolean.TRUE), + null); + BSPTree a6 = + new BSPTree<>(buildHalfLine(new Vector2D(0.82, -0.18), + new Vector2D(0.85, -0.15), + true), + new BSPTree<>(Boolean.FALSE), a5, null); + BSPTree a7 = + new BSPTree<>(buildHalfLine(new Vector2D(0.85, -0.05), + new Vector2D(0.82, -0.08), + false), + a4, a6, null); + BSPTree a8 = + new BSPTree<>(buildLine(new Vector2D(0.85, -0.25), + new Vector2D(0.85, 0.05)), + a2, a7, null); + BSPTree a9 = + new BSPTree<>(buildLine(new Vector2D(0.90, 0.05), + new Vector2D(0.90, -0.50)), + a8, new BSPTree<>(Boolean.FALSE), null); + + BSPTree b0 = + new BSPTree<>(buildSegment(new Vector2D(0.92, -0.12), + new Vector2D(0.92, -0.08)), + new BSPTree<>(Boolean.FALSE), new BSPTree<>(Boolean.TRUE), + null); + BSPTree b1 = + new BSPTree<>(buildHalfLine(new Vector2D(0.92, -0.08), + new Vector2D(0.90, -0.10), + true), + new BSPTree<>(Boolean.FALSE), b0, null); + BSPTree b2 = + new BSPTree<>(buildSegment(new Vector2D(0.92, -0.18), + new Vector2D(0.92, -0.12)), + new BSPTree<>(Boolean.FALSE), new BSPTree<>(Boolean.TRUE), + null); + BSPTree b3 = + new BSPTree<>(buildSegment(new Vector2D(0.85, -0.15), + new Vector2D(0.90, -0.20)), + new BSPTree<>(Boolean.FALSE), b2, null); + BSPTree b4 = + new BSPTree<>(buildSegment(new Vector2D(0.95, -0.15), + new Vector2D(0.85, -0.05)), + b1, b3, null); + BSPTree b5 = + new BSPTree<>(buildHalfLine(new Vector2D(0.85, -0.05), + new Vector2D(0.85, -0.25), + true), + new BSPTree<>(Boolean.FALSE), b4, null); + BSPTree b6 = + new BSPTree<>(buildLine(new Vector2D(0.0, -1.10), + new Vector2D(1.0, -0.10)), + new BSPTree<>(Boolean.FALSE), b5, null); PolygonsSet c = - (PolygonsSet) new RegionFactory().union(new PolygonsSet(a9, 1.0e-10), - new PolygonsSet(b6, 1.0e-10)); + (PolygonsSet) new RegionFactory().union(new PolygonsSet(a9, 1.0e-10), + new PolygonsSet(b6, 1.0e-10)); checkPoints(Region.Location.INSIDE, c, new Vector2D[] { new Vector2D(0.83, -0.06), @@ -878,34 +874,35 @@ void testBug20041003() { new Vector2D(1.0, 2.0), 1.0e-10) }; - BSPTree node1 = - new BSPTree(new SubLine(l[0], - new IntervalsSet(intersectionAbscissa(l[0], l[1]), - intersectionAbscissa(l[0], l[2]), - 1.0e-10)), - new BSPTree(Boolean.TRUE), - new BSPTree(Boolean.FALSE), - null); - BSPTree node2 = - new BSPTree(new SubLine(l[1], - new IntervalsSet(intersectionAbscissa(l[1], l[2]), - intersectionAbscissa(l[1], l[3]), - 1.0e-10)), - node1, - new BSPTree(Boolean.FALSE), - null); - BSPTree node3 = - new BSPTree(new SubLine(l[2], - new IntervalsSet(intersectionAbscissa(l[2], l[3]), - Double.POSITIVE_INFINITY, 1.0e-10)), + BSPTree node1 = + new BSPTree<>(new SubLine(l[0], + new IntervalsSet(intersectionAbscissa(l[0], l[1]), + intersectionAbscissa(l[0], l[2]), + 1.0e-10)), + new BSPTree<>(Boolean.TRUE), + new BSPTree<>(Boolean.FALSE), + null); + BSPTree node2 = + new BSPTree<>(new SubLine(l[1], + new IntervalsSet(intersectionAbscissa(l[1], l[2]), + intersectionAbscissa(l[1], l[3]), + 1.0e-10)), + node1, + new BSPTree<>(Boolean.FALSE), + null); + BSPTree node3 = + new BSPTree<>(new SubLine(l[2], + new IntervalsSet(intersectionAbscissa(l[2], l[3]), + Double.POSITIVE_INFINITY, + 1.0e-10)), node2, - new BSPTree(Boolean.FALSE), - null); - BSPTree node4 = - new BSPTree(l[3].wholeHyperplane(), - node3, - new BSPTree(Boolean.FALSE), - null); + new BSPTree<>(Boolean.FALSE), + null); + BSPTree node4 = + new BSPTree<>(l[3].wholeHyperplane(), + node3, + new BSPTree<>(Boolean.FALSE), + null); PolygonsSet set = new PolygonsSet(node4, 1.0e-10); assertEquals(0, set.getVertices().length); @@ -1087,11 +1084,10 @@ void testIssue880Complete() { }; PolygonsSet set2 = new PolygonsSet(1.0e-8, vertices2); PolygonsSet set = (PolygonsSet) new - RegionFactory().difference(set1.copySelf(), - set2.copySelf()); + RegionFactory().difference(set1.copySelf(), set2.copySelf()); Vector2D[][] vertices = set.getVertices(); - assertTrue(vertices[0][0] != null); + assertNotNull(vertices[0][0]); assertEquals(1, vertices.length); } @@ -1107,7 +1103,7 @@ void testWrongUsage() { // the following is a wrong usage of the constructor. // as explained in the javadoc, the failure is NOT detected at construction // time but occurs later on - PolygonsSet ps = new PolygonsSet(new BSPTree(), 1.0e-10); + PolygonsSet ps = new PolygonsSet(new BSPTree<>(), 1.0e-10); assertNotNull(ps); try { ps.getSize(); @@ -1139,34 +1135,34 @@ void testIssue1162() { @Test void testThinRectangle() { - RegionFactory factory = new RegionFactory(); + RegionFactory factory = new RegionFactory<>(); Vector2D pA = new Vector2D(0.0, 1.0); Vector2D pB = new Vector2D(0.0, 0.0); Vector2D pC = new Vector2D(1.0 / 64.0, 0.0); Vector2D pD = new Vector2D(1.0 / 64.0, 1.0); // if tolerance is smaller than rectangle width, the rectangle is computed accurately - Hyperplane[] h1 = new Line[] { + Hyperplane[] h1 = new Line[] { new Line(pA, pB, 1.0 / 256), new Line(pB, pC, 1.0 / 256), new Line(pC, pD, 1.0 / 256), new Line(pD, pA, 1.0 / 256) }; - Region accuratePolygon = factory.buildConvex(h1); + Region accuratePolygon = factory.buildConvex(h1); assertEquals(1.0 / 64.0, accuratePolygon.getSize(), 1.0e-10); - assertTrue(Double.isInfinite(new RegionFactory().getComplement(accuratePolygon).getSize())); + assertTrue(Double.isInfinite(new RegionFactory().getComplement(accuratePolygon).getSize())); assertEquals(2 * (1.0 + 1.0 / 64.0), accuratePolygon.getBoundarySize(), 1.0e-10); // if tolerance is larger than rectangle width, the rectangle degenerates // as of 3.3, its two long edges cannot be distinguished anymore and this part of the test did fail // this has been fixed in 3.4 (issue MATH-1174) - Hyperplane[] h2 = new Line[] { + Hyperplane[] h2 = new Line[] { new Line(pA, pB, 1.0 / 16), new Line(pB, pC, 1.0 / 16), new Line(pC, pD, 1.0 / 16), new Line(pD, pA, 1.0 / 16) }; - Region degeneratedPolygon = factory.buildConvex(h2); + Region degeneratedPolygon = factory.buildConvex(h2); assertEquals(0.0, degeneratedPolygon.getSize(), 1.0e-10); assertTrue(degeneratedPolygon.isEmpty()); @@ -1176,7 +1172,7 @@ void testThinRectangle() { void testInconsistentHyperplanes() { assertThrows(MathIllegalArgumentException.class, () -> { double tolerance = 1.0e-10; - new RegionFactory().buildConvex(new Line(new Vector2D(0, 0), new Vector2D(0, 1), tolerance), + new RegionFactory().buildConvex(new Line(new Vector2D(0, 0), new Vector2D(0, 1), tolerance), new Line(new Vector2D(1, 1), new Vector2D(1, 0), tolerance)); }); } @@ -1233,7 +1229,7 @@ void testOppositeEdges() { @Test void testInfiniteQuadrant() { final double tolerance = 1.0e-10; - BSPTree bsp = new BSPTree<>(); + BSPTree bsp = new BSPTree<>(); bsp.insertCut(new Line(Vector2D.ZERO, 0.0, tolerance)); bsp.getPlus().setAttribute(Boolean.FALSE); bsp.getMinus().insertCut(new Line(Vector2D.ZERO, 0.5 * FastMath.PI, tolerance)); @@ -1291,7 +1287,7 @@ void testZigZagBoundaryOversampledIssue46() { // check original points are on the boundary assertEquals(Location.BOUNDARY, zone.checkPoint(vertex), "" + vertex); double offset = FastMath.abs(zone.projectToBoundary(vertex).getOffset()); - assertEquals(0, offset, cornerTol, "" + vertex + " offset: " + offset); + assertEquals(0, offset, cornerTol, vertex + " offset: " + offset); } } @@ -1320,7 +1316,7 @@ void testPositiveQuadrantByVerticesDetailIssue46() { Collections.reverse(points); PolygonsSet set = new PolygonsSet(tol, points.toArray(new Vector2D[0])); RandomVectorGenerator random = - new UncorrelatedRandomVectorGenerator(2, new UniformRandomGenerator(new Well1024a(0xb8fc5acc91044308l))); + new UncorrelatedRandomVectorGenerator(2, new UniformRandomGenerator(new Well1024a(0xb8fc5acc91044308L))); /* Where exactly the boundaries fall depends on which points are kept from * decimation, which can vary by up to tol. So a point up to 2*tol away from a * input point may be on the boundary. All input points are guaranteed to be on @@ -1390,14 +1386,14 @@ private static class Counter { public void count(PolygonsSet polygonsSet) { leafNodes = 0; internalNodes = 0; - polygonsSet.getTree(false).visit(new BSPTreeVisitor() { - public Order visitOrder(BSPTree node) { + polygonsSet.getTree(false).visit(new BSPTreeVisitor() { + public Order visitOrder(BSPTree node) { return Order.SUB_PLUS_MINUS; } - public void visitInternalNode(BSPTree node) { + public void visitInternalNode(BSPTree node) { ++internalNodes; } - public void visitLeafNode(BSPTree node) { + public void visitLeafNode(BSPTree node) { ++leafNodes; } @@ -1415,17 +1411,17 @@ public int getLeafNodes() { } private PolygonsSet buildSet(Vector2D[][] vertices) { - ArrayList> edges = new ArrayList>(); - for (int i = 0; i < vertices.length; ++i) { - int l = vertices[i].length; + ArrayList> edges = new ArrayList<>(); + for (final Vector2D[] vertex : vertices) { + int l = vertex.length; for (int j = 0; j < l; ++j) { - edges.add(buildSegment(vertices[i][j], vertices[i][(j + 1) % l])); + edges.add(buildSegment(vertex[j], vertex[(j + 1) % l])); } } return new PolygonsSet(edges, 1.0e-10); } - private SubHyperplane buildLine(Vector2D start, Vector2D end) { + private SubHyperplane buildLine(Vector2D start, Vector2D end) { return new Line(start, end, 1.0e-10).wholeHyperplane(); } @@ -1434,25 +1430,24 @@ private double intersectionAbscissa(Line l0, Line l1) { return (l0.toSubSpace(p)).getX(); } - private SubHyperplane buildHalfLine(Vector2D start, Vector2D end, - boolean startIsVirtual) { + private SubHyperplane buildHalfLine(Vector2D start, Vector2D end, + boolean startIsVirtual) { Line line = new Line(start, end, 1.0e-10); double lower = startIsVirtual ? Double.NEGATIVE_INFINITY : (line.toSubSpace(start)).getX(); double upper = startIsVirtual ? (line.toSubSpace(end)).getX() : Double.POSITIVE_INFINITY; return new SubLine(line, new IntervalsSet(lower, upper, 1.0e-10)); } - private SubHyperplane buildSegment(Vector2D start, Vector2D end) { + private SubHyperplane buildSegment(Vector2D start, Vector2D end) { Line line = new Line(start, end, 1.0e-10); double lower = (line.toSubSpace(start)).getX(); double upper = (line.toSubSpace(end)).getX(); return new SubLine(line, new IntervalsSet(lower, upper, 1.0e-10)); } - private void checkPoints(Region.Location expected, PolygonsSet set, - Vector2D[] points) { - for (int i = 0; i < points.length; ++i) { - assertEquals(expected, set.checkPoint(points[i])); + private void checkPoints(Region.Location expected, PolygonsSet set, Vector2D[] points) { + for (final Vector2D point : points) { + assertEquals(expected, set.checkPoint(point)); } } @@ -1476,15 +1471,13 @@ private void checkVertices(Vector2D[][] rebuiltVertices, Vector2D[][] vertices) { // each rebuilt vertex should be in a segment joining two original vertices - for (int i = 0; i < rebuiltVertices.length; ++i) { - for (int j = 0; j < rebuiltVertices[i].length; ++j) { - boolean inSegment = false; - Vector2D p = rebuiltVertices[i][j]; - for (int k = 0; k < vertices.length; ++k) { - Vector2D[] loop = vertices[k]; + for (final Vector2D[] rebuiltVertex : rebuiltVertices) { + for (final Vector2D vertex : rebuiltVertex) { + boolean inSegment = false; + for (Vector2D[] loop : vertices) { int length = loop.length; - for (int l = 0; (! inSegment) && (l < length); ++l) { - inSegment = checkInSegment(p, loop[l], loop[(l + 1) % length], 1.0e-10); + for (int l = 0; (!inSegment) && (l < length); ++l) { + inSegment = checkInSegment(vertex, loop[l], loop[(l + 1) % length], 1.0e-10); } } assertTrue(inSegment); @@ -1492,13 +1485,12 @@ private void checkVertices(Vector2D[][] rebuiltVertices, } // each original vertex should have a corresponding rebuilt vertex - for (int k = 0; k < vertices.length; ++k) { - for (int l = 0; l < vertices[k].length; ++l) { + for (final Vector2D[] vertex : vertices) { + for (final Vector2D vector2D : vertex) { double min = Double.POSITIVE_INFINITY; - for (int i = 0; i < rebuiltVertices.length; ++i) { - for (int j = 0; j < rebuiltVertices[i].length; ++j) { - min = FastMath.min(vertices[k][l].distance(rebuiltVertices[i][j]), - min); + for (final Vector2D[] rebuiltVertex : rebuiltVertices) { + for (final Vector2D d : rebuiltVertex) { + min = FastMath.min(vector2D.distance(d), min); } } assertEquals(0.0, min, 1.0e-10); diff --git a/hipparchus-geometry/src/test/java/org/hipparchus/geometry/euclidean/twod/SubLineTest.java b/hipparchus-geometry/src/test/java/org/hipparchus/geometry/euclidean/twod/SubLineTest.java index b6485c0c0..829a16f8e 100644 --- a/hipparchus-geometry/src/test/java/org/hipparchus/geometry/euclidean/twod/SubLineTest.java +++ b/hipparchus-geometry/src/test/java/org/hipparchus/geometry/euclidean/twod/SubLineTest.java @@ -23,6 +23,7 @@ import org.hipparchus.geometry.euclidean.oned.Euclidean1D; import org.hipparchus.geometry.euclidean.oned.IntervalsSet; +import org.hipparchus.geometry.euclidean.oned.Vector1D; import org.hipparchus.geometry.partitioning.RegionFactory; import org.junit.jupiter.api.Test; @@ -64,7 +65,7 @@ void testNoEndPoints() { @Test void testNoSegments() { SubLine empty = new SubLine(new Line(new Vector2D(-1, -7), new Vector2D(7, -1), 1.0e-10), - new RegionFactory().getComplement(new IntervalsSet(1.0e-10))); + new RegionFactory().getComplement(new IntervalsSet(1.0e-10))); List segments = empty.getSegments(); assertEquals(0, segments.size()); } @@ -72,8 +73,8 @@ void testNoSegments() { @Test void testSeveralSegments() { SubLine twoSubs = new SubLine(new Line(new Vector2D(-1, -7), new Vector2D(7, -1), 1.0e-10), - new RegionFactory().union(new IntervalsSet(1, 2, 1.0e-10), - new IntervalsSet(3, 4, 1.0e-10))); + new RegionFactory(). + union(new IntervalsSet(1, 2, 1.0e-10), new IntervalsSet(3, 4, 1.0e-10))); List segments = twoSubs.getSegments(); assertEquals(2, segments.size()); } diff --git a/hipparchus-geometry/src/test/java/org/hipparchus/geometry/euclidean/twod/hull/ConvexHullGenerator2DAbstractTest.java b/hipparchus-geometry/src/test/java/org/hipparchus/geometry/euclidean/twod/hull/ConvexHullGenerator2DAbstractTest.java index 478a085a3..27a7ee368 100644 --- a/hipparchus-geometry/src/test/java/org/hipparchus/geometry/euclidean/twod/hull/ConvexHullGenerator2DAbstractTest.java +++ b/hipparchus-geometry/src/test/java/org/hipparchus/geometry/euclidean/twod/hull/ConvexHullGenerator2DAbstractTest.java @@ -37,6 +37,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNotSame; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -67,14 +68,12 @@ public void setUp() { @Test public void testNullArgument() { - assertThrows(NullArgumentException.class, () -> { - generator.generate(null); - }); + assertThrows(NullArgumentException.class, () -> generator.generate(null)); } @Test public void testEmpty() { - ConvexHull2D hull = generator.generate(Collections.emptyList()); + ConvexHull2D hull = generator.generate(Collections.emptyList()); assertEquals(0, hull.getVertices().length); assertEquals(0, hull.getLineSegments().length); } @@ -97,7 +96,7 @@ public void testTwoPoints() { @Test public void testAllIdentical() { - final Collection points = new ArrayList(); + final Collection points = new ArrayList<>(); points.add(new Vector2D(1, 1)); points.add(new Vector2D(1, 1)); points.add(new Vector2D(1, 1)); @@ -122,7 +121,7 @@ public void testConvexHull() { @Test public void testCollinearPoints() { - final Collection points = new ArrayList(); + final Collection points = new ArrayList<>(); points.add(new Vector2D(1, 1)); points.add(new Vector2D(2, 2)); points.add(new Vector2D(2, 4)); @@ -135,7 +134,7 @@ public void testCollinearPoints() { @Test public void testCollinearPointsReverse() { - final Collection points = new ArrayList(); + final Collection points = new ArrayList<>(); points.add(new Vector2D(1, 1)); points.add(new Vector2D(2, 2)); points.add(new Vector2D(2, 4)); @@ -148,7 +147,7 @@ public void testCollinearPointsReverse() { @Test public void testCollinearPointsIncluded() { - final Collection points = new ArrayList(); + final Collection points = new ArrayList<>(); points.add(new Vector2D(1, 1)); points.add(new Vector2D(2, 2)); points.add(new Vector2D(2, 4)); @@ -161,7 +160,7 @@ public void testCollinearPointsIncluded() { @Test public void testCollinearPointsIncludedReverse() { - final Collection points = new ArrayList(); + final Collection points = new ArrayList<>(); points.add(new Vector2D(1, 1)); points.add(new Vector2D(2, 2)); points.add(new Vector2D(2, 4)); @@ -174,7 +173,7 @@ public void testCollinearPointsIncludedReverse() { @Test public void testIdenticalPoints() { - final Collection points = new ArrayList(); + final Collection points = new ArrayList<>(); points.add(new Vector2D(1, 1)); points.add(new Vector2D(2, 2)); points.add(new Vector2D(2, 4)); @@ -187,7 +186,7 @@ public void testIdenticalPoints() { @Test public void testIdenticalPoints2() { - final Collection points = new ArrayList(); + final Collection points = new ArrayList<>(); points.add(new Vector2D(1, 1)); points.add(new Vector2D(2, 2)); points.add(new Vector2D(2, 4)); @@ -200,7 +199,7 @@ public void testIdenticalPoints2() { @Test public void testClosePoints() { - final Collection points = new ArrayList(); + final Collection points = new ArrayList<>(); points.add(new Vector2D(1, 1)); points.add(new Vector2D(2, 2)); points.add(new Vector2D(2, 4)); @@ -215,7 +214,7 @@ public void testClosePoints() { public void testCollinearPointOnExistingBoundary() { // MATH-1135: check that collinear points on the hull are handled correctly // when only a minimal hull shall be constructed - final Collection points = new ArrayList(); + final Collection points = new ArrayList<>(); points.add(new Vector2D(7.3152, 34.7472)); points.add(new Vector2D(6.400799999999997, 34.747199999999985)); points.add(new Vector2D(5.486399999999997, 34.7472)); @@ -237,7 +236,7 @@ public void testCollinearPointsInAnyOrder() { // make sure that they are processed in the proper order // for each algorithm. - List points = new ArrayList(); + List points = new ArrayList<>(); // first case: 3 points are collinear points.add(new Vector2D(16.078200000000184, -36.52519999989808)); @@ -274,7 +273,7 @@ public void testCollinearPointsInAnyOrder() { @Test public void testIssue1123() { - List points = new ArrayList(); + List points = new ArrayList<>(); int[][] data = new int[][] { { -11, -1 }, { -11, 0 }, { -11, 1 }, { -10, -3 }, { -10, -2 }, { -10, -1 }, { -10, 0 }, { -10, 1 }, @@ -351,7 +350,7 @@ public void testIssue1123() { }; ConvexHull2D convHull = generator.generate(points); - Region hullRegion = convHull.createRegion(); + Region hullRegion = convHull.createRegion(); assertEquals(274.0, hullRegion.getSize(), 1.0e-12); double perimeter = 0; @@ -361,8 +360,8 @@ public void testIssue1123() { } assertEquals(perimeter, hullRegion.getBoundarySize(), 1.0e-12); - for (int i = 0; i < referenceHull.length; ++i) { - assertEquals(Location.BOUNDARY, hullRegion.checkPoint(referenceHull[i])); + for (final Vector2D v : referenceHull) { + assertEquals(Location.BOUNDARY, hullRegion.checkPoint(v)); } } @@ -371,7 +370,7 @@ public void testIssue1123() { protected final List createRandomPoints(int size) { // create the cloud container - List points = new ArrayList(size); + List points = new ArrayList<>(size); // fill the cloud with a random distribution of points for (int i = 0; i < size; i++) { points.add(new Vector2D(random.nextDouble() * 2.0 - 1.0, random.nextDouble() * 2.0 - 1.0)); @@ -436,11 +435,11 @@ protected final void checkPointsInsideHullRegion(final Collection poin final boolean includesCollinearPoints) { final Collection hullVertices = Arrays.asList(hull.getVertices()); - final Region region = hull.createRegion(); + final Region region = hull.createRegion(); for (final Vector2D p : points) { Location location = region.checkPoint(p); - assertTrue(location != Location.OUTSIDE); + assertNotSame(location, Location.OUTSIDE); if (location == Location.BOUNDARY && includesCollinearPoints) { assertTrue(hullVertices.contains(p)); diff --git a/hipparchus-geometry/src/test/java/org/hipparchus/geometry/partitioning/RegionDumper.java b/hipparchus-geometry/src/test/java/org/hipparchus/geometry/partitioning/RegionDumper.java index 1850f7b4d..1eb444a1c 100644 --- a/hipparchus-geometry/src/test/java/org/hipparchus/geometry/partitioning/RegionDumper.java +++ b/hipparchus-geometry/src/test/java/org/hipparchus/geometry/partitioning/RegionDumper.java @@ -24,6 +24,7 @@ import java.util.Formatter; import java.util.Locale; +import org.hipparchus.geometry.Point; import org.hipparchus.geometry.Space; import org.hipparchus.geometry.euclidean.oned.Euclidean1D; import org.hipparchus.geometry.euclidean.oned.IntervalsSet; @@ -39,8 +40,10 @@ import org.hipparchus.geometry.euclidean.twod.Vector2D; import org.hipparchus.geometry.spherical.oned.ArcsSet; import org.hipparchus.geometry.spherical.oned.LimitAngle; +import org.hipparchus.geometry.spherical.oned.S1Point; import org.hipparchus.geometry.spherical.oned.Sphere1D; import org.hipparchus.geometry.spherical.twod.Circle; +import org.hipparchus.geometry.spherical.twod.S2Point; import org.hipparchus.geometry.spherical.twod.Sphere2D; import org.hipparchus.geometry.spherical.twod.SphericalPolygonsSet; @@ -62,11 +65,12 @@ private RegionDumper() { * @return string representation of the region */ public static String dump(final ArcsSet arcsSet) { - final TreeDumper visitor = new TreeDumper("ArcsSet", arcsSet.getTolerance()) { + final TreeDumper visitor = + new TreeDumper("ArcsSet", arcsSet.getTolerance()) { /** {@inheritDoc} */ @Override - protected void formatHyperplane(final Hyperplane hyperplane) { + protected void formatHyperplane(final Hyperplane hyperplane) { final LimitAngle h = (LimitAngle) hyperplane; getFormatter().format("%22.15e %b %22.15e", h.getLocation().getAlpha(), h.isDirect(), h.getTolerance()); @@ -82,11 +86,12 @@ protected void formatHyperplane(final Hyperplane hyperplane) { * @return string representation of the region */ public static String dump(final SphericalPolygonsSet sphericalPolygonsSet) { - final TreeDumper visitor = new TreeDumper("SphericalPolygonsSet", sphericalPolygonsSet.getTolerance()) { + final TreeDumper visitor = + new TreeDumper("SphericalPolygonsSet", sphericalPolygonsSet.getTolerance()) { /** {@inheritDoc} */ @Override - protected void formatHyperplane(final Hyperplane hyperplane) { + protected void formatHyperplane(final Hyperplane hyperplane) { final Circle h = (Circle) hyperplane; getFormatter().format("%22.15e %22.15e %22.15e %22.15e", h.getPole().getX(), h.getPole().getY(), h.getPole().getZ(), @@ -103,11 +108,12 @@ protected void formatHyperplane(final Hyperplane hyperplane) { * @return string representation of the region */ public static String dump(final IntervalsSet intervalsSet) { - final TreeDumper visitor = new TreeDumper("IntervalsSet", intervalsSet.getTolerance()) { + final TreeDumper visitor = + new TreeDumper("IntervalsSet", intervalsSet.getTolerance()) { /** {@inheritDoc} */ @Override - protected void formatHyperplane(final Hyperplane hyperplane) { + protected void formatHyperplane(final Hyperplane hyperplane) { final OrientedPoint h = (OrientedPoint) hyperplane; getFormatter().format("%22.15e %b %22.15e", h.getLocation().getX(), h.isDirect(), h.getTolerance()); @@ -123,11 +129,12 @@ protected void formatHyperplane(final Hyperplane hyperplane) { * @return string representation of the region */ public static String dump(final PolygonsSet polygonsSet) { - final TreeDumper visitor = new TreeDumper("PolygonsSet", polygonsSet.getTolerance()) { + final TreeDumper visitor = + new TreeDumper("PolygonsSet", polygonsSet.getTolerance()) { /** {@inheritDoc} */ @Override - protected void formatHyperplane(final Hyperplane hyperplane) { + protected void formatHyperplane(final Hyperplane hyperplane) { final Line h = (Line) hyperplane; final Vector2D p = h.toSpace(Vector1D.ZERO); getFormatter().format("%22.15e %22.15e %22.15e %22.15e", @@ -144,11 +151,12 @@ protected void formatHyperplane(final Hyperplane hyperplane) { * @return string representation of the region */ public static String dump(final PolyhedronsSet polyhedronsSet) { - final TreeDumper visitor = new TreeDumper("PolyhedronsSet", polyhedronsSet.getTolerance()) { + final TreeDumper visitor = + new TreeDumper("PolyhedronsSet", polyhedronsSet.getTolerance()) { /** {@inheritDoc} */ @Override - protected void formatHyperplane(final Hyperplane hyperplane) { + protected void formatHyperplane(final Hyperplane hyperplane) { final Plane h = (Plane) hyperplane; final Vector3D p = h.toSpace(Vector2D.ZERO); getFormatter().format("%22.15e %22.15e %22.15e %22.15e %22.15e %22.15e %22.15e", @@ -164,8 +172,9 @@ protected void formatHyperplane(final Hyperplane hyperplane) { /** Dumping visitor. * @param Type of the space. + * @param

Type of the points in space. */ - private abstract static class TreeDumper implements BSPTreeVisitor { + private abstract static class TreeDumper> implements BSPTreeVisitor { /** Builder for the string representation of the dumped tree. */ private final StringBuilder dump; @@ -205,17 +214,17 @@ protected Formatter getFormatter() { /** Format a string representation of the hyperplane underlying a cut sub-hyperplane. * @param hyperplane hyperplane to format */ - protected abstract void formatHyperplane(Hyperplane hyperplane); + protected abstract void formatHyperplane(Hyperplane hyperplane); /** {@inheritDoc} */ @Override - public Order visitOrder(final BSPTree node) { + public Order visitOrder(final BSPTree node) { return Order.SUB_MINUS_PLUS; } /** {@inheritDoc} */ @Override - public void visitInternalNode(final BSPTree node) { + public void visitInternalNode(final BSPTree node) { formatter.format("%s %s internal ", prefix, type(node)); formatHyperplane(node.getCut().getHyperplane()); formatter.format("%n"); @@ -224,10 +233,10 @@ public void visitInternalNode(final BSPTree node) { /** {@inheritDoc} */ @Override - public void visitLeafNode(final BSPTree node) { + public void visitLeafNode(final BSPTree node) { formatter.format("%s %s leaf %s%n", prefix, type(node), node.getAttribute()); - for (BSPTree n = node; + for (BSPTree n = node; n.getParent() != null && n == n.getParent().getPlus(); n = n.getParent()) { prefix = prefix.substring(0, prefix.length() - 2); @@ -239,7 +248,7 @@ public void visitLeafNode(final BSPTree node) { * @return "plus " or "minus" depending on the node being the plus or minus * child of its parent ("plus " is arbitrarily returned for the root node) */ - private String type(final BSPTree node) { + private String type(final BSPTree node) { return (node.getParent() != null && node == node.getParent().getMinus()) ? "minus" : "plus "; } diff --git a/hipparchus-geometry/src/test/java/org/hipparchus/geometry/partitioning/RegionParser.java b/hipparchus-geometry/src/test/java/org/hipparchus/geometry/partitioning/RegionParser.java index 191115d96..8f2c93701 100644 --- a/hipparchus-geometry/src/test/java/org/hipparchus/geometry/partitioning/RegionParser.java +++ b/hipparchus-geometry/src/test/java/org/hipparchus/geometry/partitioning/RegionParser.java @@ -25,6 +25,7 @@ import java.text.ParseException; import java.util.StringTokenizer; +import org.hipparchus.geometry.Point; import org.hipparchus.geometry.Space; import org.hipparchus.geometry.euclidean.oned.Euclidean1D; import org.hipparchus.geometry.euclidean.oned.IntervalsSet; @@ -43,6 +44,7 @@ import org.hipparchus.geometry.spherical.oned.S1Point; import org.hipparchus.geometry.spherical.oned.Sphere1D; import org.hipparchus.geometry.spherical.twod.Circle; +import org.hipparchus.geometry.spherical.twod.S2Point; import org.hipparchus.geometry.spherical.twod.Sphere2D; import org.hipparchus.geometry.spherical.twod.SphericalPolygonsSet; @@ -67,7 +69,8 @@ private RegionParser() { */ public static ArcsSet parseArcsSet(final String s) throws IOException, ParseException { - final TreeBuilder builder = new TreeBuilder("ArcsSet", s) { + final TreeBuilder builder = + new TreeBuilder("ArcsSet", s) { /** {@inheritDoc} */ @Override @@ -88,12 +91,13 @@ protected LimitAngle parseHyperplane() */ public static SphericalPolygonsSet parseSphericalPolygonsSet(final String s) throws IOException, ParseException { - final TreeBuilder builder = new TreeBuilder("SphericalPolygonsSet", s) { + final TreeBuilder builder = + new TreeBuilder("SphericalPolygonsSet", s) { /** {@inheritDoc} */ @Override public Circle parseHyperplane() - throws IOException, ParseException { + throws IOException { return new Circle(new Vector3D(getNumber(), getNumber(), getNumber()), getNumber()); } @@ -109,7 +113,8 @@ public Circle parseHyperplane() */ public static IntervalsSet parseIntervalsSet(final String s) throws IOException, ParseException { - final TreeBuilder builder = new TreeBuilder("IntervalsSet", s) { + final TreeBuilder builder = + new TreeBuilder("IntervalsSet", s) { /** {@inheritDoc} */ @Override @@ -130,12 +135,13 @@ public OrientedPoint parseHyperplane() */ public static PolygonsSet parsePolygonsSet(final String s) throws IOException, ParseException { - final TreeBuilder builder = new TreeBuilder("PolygonsSet", s) { + final TreeBuilder builder = + new TreeBuilder("PolygonsSet", s) { /** {@inheritDoc} */ @Override public Line parseHyperplane() - throws IOException, ParseException { + throws IOException { return new Line(new Vector2D(getNumber(), getNumber()), getNumber(), getNumber()); } @@ -151,12 +157,13 @@ public Line parseHyperplane() */ public static PolyhedronsSet parsePolyhedronsSet(final String s) throws IOException, ParseException { - final TreeBuilder builder = new TreeBuilder("PolyhedronsSet", s) { + final TreeBuilder builder = + new TreeBuilder("PolyhedronsSet", s) { /** {@inheritDoc} */ @Override public Plane parseHyperplane() - throws IOException, ParseException { + throws IOException { return new Plane(new Vector3D(getNumber(), getNumber(), getNumber()), new Vector3D(getNumber(), getNumber(), getNumber()), getNumber()); @@ -168,8 +175,9 @@ public Plane parseHyperplane() /** Local class for building an {@link AbstractRegion} tree. * @param Type of the space. + * @param

Type of the points in space. */ - private abstract static class TreeBuilder { + private abstract static class TreeBuilder> { /** Keyword for tolerance. */ private static final String TOLERANCE = "tolerance"; @@ -193,7 +201,7 @@ private abstract static class TreeBuilder { private static final String FALSE = "false"; /** Tree root. */ - private BSPTree root; + private BSPTree root; /** Tolerance. */ private final double tolerance; @@ -215,7 +223,7 @@ public TreeBuilder(final String type, final String s) getWord(TOLERANCE); tolerance = getNumber(); getWord(PLUS); - root = new BSPTree(); + root = new BSPTree<>(); parseTree(root); if (tokenizer.hasMoreTokens()) { throw new ParseException("unexpected " + tokenizer.nextToken(), 0); @@ -227,7 +235,7 @@ public TreeBuilder(final String type, final String s) * @exception IOException if the string cannot be read * @exception ParseException if the string cannot be parsed */ - private void parseTree(final BSPTree node) + private void parseTree(final BSPTree node) throws IOException, ParseException { if (INTERNAL.equals(getWord(INTERNAL, LEAF))) { // this is an internal node, it has a cut sub-hyperplane (stored as a whole hyperplane) @@ -246,11 +254,10 @@ private void parseTree(final BSPTree node) /** Get next word. * @param allowed allowed values * @return parsed word - * @exception IOException if the string cannot be read * @exception ParseException if the string cannot be parsed */ protected String getWord(final String ... allowed) - throws IOException, ParseException { + throws ParseException { final String token = tokenizer.nextToken(); for (final String a : allowed) { if (a.equals(token)) { @@ -283,7 +290,7 @@ protected boolean getBoolean() /** Get the built tree. * @return built tree */ - public BSPTree getTree() { + public BSPTree getTree() { return root; } @@ -299,7 +306,7 @@ public double getTolerance() { * @exception IOException if the string cannot be read * @exception ParseException if the string cannot be parsed */ - protected abstract Hyperplane parseHyperplane() + protected abstract Hyperplane parseHyperplane() throws IOException, ParseException; } diff --git a/hipparchus-geometry/src/test/java/org/hipparchus/geometry/spherical/oned/ArcsSetTest.java b/hipparchus-geometry/src/test/java/org/hipparchus/geometry/spherical/oned/ArcsSetTest.java index a93ff3c95..efe577660 100644 --- a/hipparchus-geometry/src/test/java/org/hipparchus/geometry/spherical/oned/ArcsSetTest.java +++ b/hipparchus-geometry/src/test/java/org/hipparchus/geometry/spherical/oned/ArcsSetTest.java @@ -125,16 +125,12 @@ void testSplitAtEnd() { @Test void testWrongInterval() { - assertThrows(MathIllegalArgumentException.class, () -> { - new ArcsSet(1.2, 0.0, 1.0e-10); - }); + assertThrows(MathIllegalArgumentException.class, () -> new ArcsSet(1.2, 0.0, 1.0e-10)); } @Test void testTooSmallTolerance() { - assertThrows(MathIllegalArgumentException.class, () -> { - new ArcsSet(0.0, 1.0, 0.9 * Sphere1D.SMALLEST_TOLERANCE); - }); + assertThrows(MathIllegalArgumentException.class, () -> new ArcsSet(0.0, 1.0, 0.9 * Sphere1D.SMALLEST_TOLERANCE)); } @Test @@ -167,7 +163,7 @@ void testFullCircle() { @Test void testEmpty() { - ArcsSet empty = (ArcsSet) new RegionFactory().getComplement(new ArcsSet(1.0e-10)); + ArcsSet empty = (ArcsSet) new RegionFactory().getComplement(new ArcsSet(1.0e-10)); assertEquals(1.0e-10, empty.getTolerance(), 1.0e-20); assertEquals(0.0, empty.getSize(), 1.0e-10); assertTrue(empty.asList().isEmpty()); @@ -185,7 +181,7 @@ void testTiny() { @Test void testSpecialConstruction() { - List> boundary = new ArrayList>(); + List> boundary = new ArrayList<>(); boundary.add(new LimitAngle(new S1Point(0.0), false, 1.0e-10).wholeHyperplane()); boundary.add(new LimitAngle(new S1Point(MathUtils.TWO_PI - 1.0e-11), true, 1.0e-10).wholeHyperplane()); ArcsSet set = new ArcsSet(boundary, 1.0e-10); @@ -211,7 +207,7 @@ void testDifference() { assertEquals(3.0, bList.get(0).getInf(), 1.0e-10); assertEquals(5.0, bList.get(0).getSup(), 1.0e-10); - ArcsSet aMb = (ArcsSet) new RegionFactory().difference(a, b); + ArcsSet aMb = (ArcsSet) new RegionFactory().difference(a, b); for (int k = -2; k < 3; ++k) { assertEquals(Location.OUTSIDE, aMb.checkPoint(new S1Point(0.0 + k * MathUtils.TWO_PI))); assertEquals(Location.OUTSIDE, aMb.checkPoint(new S1Point(0.9 + k * MathUtils.TWO_PI))); @@ -242,8 +238,8 @@ void testDifference() { @Test void testIntersection() { - ArcsSet a = (ArcsSet) new RegionFactory().union(new ArcsSet(1.0, 3.0, 1.0e-10), - new ArcsSet(5.0, 6.0, 1.0e-10)); + ArcsSet a = (ArcsSet) new RegionFactory(). + union(new ArcsSet(1.0, 3.0, 1.0e-10), new ArcsSet(5.0, 6.0, 1.0e-10)); List aList = a.asList(); assertEquals(2, aList.size()); assertEquals(1.0, aList.get(0).getInf(), 1.0e-10); @@ -257,7 +253,7 @@ void testIntersection() { assertEquals(0.0, bList.get(0).getInf(), 1.0e-10); assertEquals(5.5, bList.get(0).getSup(), 1.0e-10); - ArcsSet aMb = (ArcsSet) new RegionFactory().intersection(a, b); + ArcsSet aMb = (ArcsSet) new RegionFactory().intersection(a, b); for (int k = -2; k < 3; ++k) { assertEquals(Location.OUTSIDE, aMb.checkPoint(new S1Point(0.0 + k * MathUtils.TWO_PI))); assertEquals(Location.BOUNDARY, aMb.checkPoint(new S1Point(1.0 + k * MathUtils.TWO_PI))); @@ -286,7 +282,7 @@ void testIntersection() { @Test void testMultiple() { - RegionFactory factory = new RegionFactory(); + RegionFactory factory = new RegionFactory<>(); ArcsSet set = (ArcsSet) factory.intersection(factory.union(factory.difference(new ArcsSet(1.0, 6.0, 1.0e-10), new ArcsSet(3.0, 5.0, 1.0e-10)), @@ -320,8 +316,8 @@ void testSinglePoint() { @Test void testIteration() { - ArcsSet set = (ArcsSet) new RegionFactory().difference(new ArcsSet(1.0, 6.0, 1.0e-10), - new ArcsSet(3.0, 5.0, 1.0e-10)); + ArcsSet set = (ArcsSet) new RegionFactory(). + difference(new ArcsSet(1.0, 6.0, 1.0e-10), new ArcsSet(3.0, 5.0, 1.0e-10)); Iterator iterator = set.iterator(); try { iterator.remove(); @@ -354,7 +350,9 @@ void testIteration() { @Test void testEmptyTree() { - assertEquals(MathUtils.TWO_PI, new ArcsSet(new BSPTree(Boolean.TRUE), 1.0e-10).getSize(), 1.0e-10); + assertEquals(MathUtils.TWO_PI, + new ArcsSet(new BSPTree<>(Boolean.TRUE), 1.0e-10).getSize(), + 1.0e-10); } @Test @@ -362,13 +360,13 @@ void testShiftedAngles() { for (int k = -2; k < 3; ++k) { SubLimitAngle l1 = new LimitAngle(new S1Point(1.0 + k * MathUtils.TWO_PI), false, 1.0e-10).wholeHyperplane(); SubLimitAngle l2 = new LimitAngle(new S1Point(1.5 + k * MathUtils.TWO_PI), true, 1.0e-10).wholeHyperplane(); - ArcsSet set = new ArcsSet(new BSPTree(l1, - new BSPTree(Boolean.FALSE), - new BSPTree(l2, - new BSPTree(Boolean.FALSE), - new BSPTree(Boolean.TRUE), - null), - null), + ArcsSet set = new ArcsSet(new BSPTree<>(l1, + new BSPTree<>(Boolean.FALSE), + new BSPTree<>(l2, + new BSPTree<>(Boolean.FALSE), + new BSPTree<>(Boolean.TRUE), + null), + null), 1.0e-10); for (double alpha = 1.0e-6; alpha < MathUtils.TWO_PI; alpha += 0.001) { if (alpha < 1 || alpha > 1.5) { @@ -387,24 +385,21 @@ void testInconsistentState() { SubLimitAngle l1 = new LimitAngle(new S1Point(1.0), false, 1.0e-10).wholeHyperplane(); SubLimitAngle l2 = new LimitAngle(new S1Point(2.0), true, 1.0e-10).wholeHyperplane(); SubLimitAngle l3 = new LimitAngle(new S1Point(3.0), false, 1.0e-10).wholeHyperplane(); - new ArcsSet(new BSPTree(l1, - new BSPTree(Boolean.FALSE), - new BSPTree(l2, - new BSPTree(l3, - new BSPTree(Boolean.FALSE), - new BSPTree(Boolean.TRUE), - null), - new BSPTree(Boolean.TRUE), - null), - null), - 1.0e-10); + new ArcsSet(new BSPTree<>(l1, + new BSPTree<>(Boolean.FALSE), + new BSPTree<>(l2, + new BSPTree<>(l3, new BSPTree<>(Boolean.FALSE), new BSPTree<>(Boolean.TRUE), null), + new BSPTree<>(Boolean.TRUE), + null), + null), + 1.0e-10); }); } @Test void testSide() { - ArcsSet set = (ArcsSet) new RegionFactory().difference(new ArcsSet(1.0, 6.0, 1.0e-10), - new ArcsSet(3.0, 5.0, 1.0e-10)); + ArcsSet set = (ArcsSet) new RegionFactory(). + difference(new ArcsSet(1.0, 6.0, 1.0e-10), new ArcsSet(3.0, 5.0, 1.0e-10)); for (int k = -2; k < 3; ++k) { assertEquals(Side.MINUS, set.split(new Arc(0.5 + k * MathUtils.TWO_PI, 6.1 + k * MathUtils.TWO_PI, @@ -456,7 +451,7 @@ void testSideOverlapping() { @Test void testSideHyper() { - ArcsSet sub = (ArcsSet) new RegionFactory().getComplement(new ArcsSet(1.0e-10)); + ArcsSet sub = (ArcsSet) new RegionFactory().getComplement(new ArcsSet(1.0e-10)); assertTrue(sub.isEmpty()); assertEquals(Side.HYPER, sub.split(new Arc(2.0, 3.0, 1.0e-10)).getSide()); } @@ -578,13 +573,13 @@ void testFarSplit() { ArcsSet splitPlus = split.getPlus(); ArcsSet splitMinus = split.getMinus(); assertEquals(1, splitMinus.asList().size()); - assertEquals(1.0 * FastMath.PI, splitMinus.asList().get(0).getInf(), 1.0e-10); + assertEquals( FastMath.PI, splitMinus.asList().get(0).getInf(), 1.0e-10); assertEquals(1.5 * FastMath.PI, splitMinus.asList().get(0).getSup(), 1.0e-10); assertEquals(0.5 * FastMath.PI, splitMinus.getSize(), 1.0e-10); assertEquals(1, splitPlus.asList().size()); assertEquals(1.5 * FastMath.PI, splitPlus.asList().get(0).getInf(), 1.0e-10); assertEquals(2.5 * FastMath.PI, splitPlus.asList().get(0).getSup(), 1.0e-10); - assertEquals(1.0 * FastMath.PI, splitPlus.getSize(), 1.0e-10); + assertEquals( FastMath.PI, splitPlus.getSize(), 1.0e-10); } @@ -677,7 +672,7 @@ private void doTestShuffledTree(final double a0, final double a1, assertEquals(a2, setB.asList().get(1).getInf(), 1.0e-15); assertEquals(a3, setB.asList().get(1).getSup(), 1.0e-15); - final ArcsSet intersection = (ArcsSet) new RegionFactory().intersection(setA, setB); + final ArcsSet intersection = (ArcsSet) new RegionFactory().intersection(setA, setB); assertEquals((a1 - a0) + (a3 - a2), intersection.getSize(), 1.0e-10); assertEquals(2, intersection.asList().size()); assertEquals(a0, intersection.asList().get(0).getInf(), 1.0e-15); diff --git a/hipparchus-geometry/src/test/java/org/hipparchus/geometry/spherical/twod/CircleTest.java b/hipparchus-geometry/src/test/java/org/hipparchus/geometry/spherical/twod/CircleTest.java index 0cc22567c..4beac05de 100644 --- a/hipparchus-geometry/src/test/java/org/hipparchus/geometry/spherical/twod/CircleTest.java +++ b/hipparchus-geometry/src/test/java/org/hipparchus/geometry/spherical/twod/CircleTest.java @@ -142,7 +142,7 @@ void testOffset() { @Test void testInsideArc() { - RandomGenerator random = new Well1024a(0xbfd34e92231bbcfel); + RandomGenerator random = new Well1024a(0xbfd34e92231bbcfeL); UnitSphereRandomVectorGenerator sphRandom = new UnitSphereRandomVectorGenerator(3, random); for (int i = 0; i < 100; ++i) { Circle c1 = new Circle(new Vector3D(sphRandom.nextVector()), 1.0e-10); @@ -165,17 +165,17 @@ private void checkArcIsInside(final Circle arcCircle, final Circle otherCircle) @Test void testTransform() { - RandomGenerator random = new Well1024a(0x16992fc4294bf2f1l); + RandomGenerator random = new Well1024a(0x16992fc4294bf2f1L); UnitSphereRandomVectorGenerator sphRandom = new UnitSphereRandomVectorGenerator(3, random); for (int i = 0; i < 100; ++i) { Rotation r = new Rotation(new Vector3D(sphRandom.nextVector()), FastMath.PI * random.nextDouble(), RotationConvention.VECTOR_OPERATOR); - Transform t = Circle.getTransform(r); + Transform t = Circle.getTransform(r); S2Point p = new S2Point(new Vector3D(sphRandom.nextVector())); - S2Point tp = (S2Point) t.apply(p); + S2Point tp = t.apply(p); assertEquals(0.0, r.applyTo(p.getVector()).distance(tp.getVector()), 1.0e-10); Circle c = new Circle(new Vector3D(sphRandom.nextVector()), 1.0e-10); @@ -183,7 +183,7 @@ void testTransform() { assertEquals(0.0, r.applyTo(c.getPole()).distance(tc.getPole()), 1.0e-10); assertEquals(0.0, r.applyTo(c.getXAxis()).distance(tc.getXAxis()), 1.0e-10); assertEquals(0.0, r.applyTo(c.getYAxis()).distance(tc.getYAxis()), 1.0e-10); - assertEquals(c.getTolerance(), ((Circle) t.apply(c)).getTolerance(), 1.0e-10); + assertEquals(c.getTolerance(), t.apply(c).getTolerance(), 1.0e-10); SubLimitAngle sub = new LimitAngle(new S1Point(MathUtils.TWO_PI * random.nextDouble()), random.nextBoolean(), 1.0e-10).wholeHyperplane(); @@ -197,9 +197,7 @@ void testTransform() { @Test void testTooSmallTolerance() { - assertThrows(MathIllegalArgumentException.class, () -> { - new Circle(Vector3D.PLUS_K, 0.9 * Sphere2D.SMALLEST_TOLERANCE); - }); + assertThrows(MathIllegalArgumentException.class, () -> new Circle(Vector3D.PLUS_K, 0.9 * Sphere2D.SMALLEST_TOLERANCE)); } /** Check {@link Circle#getArc(S2Point, S2Point)}. */ diff --git a/hipparchus-geometry/src/test/java/org/hipparchus/geometry/spherical/twod/SphericalPolygonsSetTest.java b/hipparchus-geometry/src/test/java/org/hipparchus/geometry/spherical/twod/SphericalPolygonsSetTest.java index bc1a8c423..6d9fe0435 100644 --- a/hipparchus-geometry/src/test/java/org/hipparchus/geometry/spherical/twod/SphericalPolygonsSetTest.java +++ b/hipparchus-geometry/src/test/java/org/hipparchus/geometry/spherical/twod/SphericalPolygonsSetTest.java @@ -34,11 +34,13 @@ import org.hipparchus.geometry.partitioning.RegionFactory; import org.hipparchus.geometry.partitioning.SubHyperplane; import org.hipparchus.geometry.spherical.oned.ArcsSet; +import org.hipparchus.geometry.spherical.oned.S1Point; import org.hipparchus.geometry.spherical.oned.Sphere1D; import org.hipparchus.random.UnitSphereRandomVectorGenerator; import org.hipparchus.random.Well1024a; import org.hipparchus.util.FastMath; import org.hipparchus.util.MathUtils; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import java.lang.reflect.InvocationTargetException; @@ -49,6 +51,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; @@ -58,7 +61,7 @@ class SphericalPolygonsSetTest { void testFullSphere() { SphericalPolygonsSet full = new SphericalPolygonsSet(1.0e-10); UnitSphereRandomVectorGenerator random = - new UnitSphereRandomVectorGenerator(3, new Well1024a(0x852fd2a0ed8d2f6dl)); + new UnitSphereRandomVectorGenerator(3, new Well1024a(0x852fd2a0ed8d2f6dL)); for (int i = 0; i < 1000; ++i) { Vector3D v = new Vector3D(random.nextVector()); assertEquals(Location.INSIDE, full.checkPoint(new S2Point(v))); @@ -73,9 +76,9 @@ void testFullSphere() { @Test void testEmpty() { SphericalPolygonsSet empty = - (SphericalPolygonsSet) new RegionFactory().getComplement(new SphericalPolygonsSet(1.0e-10)); + (SphericalPolygonsSet) new RegionFactory().getComplement(new SphericalPolygonsSet(1.0e-10)); UnitSphereRandomVectorGenerator random = - new UnitSphereRandomVectorGenerator(3, new Well1024a(0x76d9205d6167b6ddl)); + new UnitSphereRandomVectorGenerator(3, new Well1024a(0x76d9205d6167b6ddL)); for (int i = 0; i < 1000; ++i) { Vector3D v = new Vector3D(random.nextVector()); assertEquals(Location.OUTSIDE, empty.checkPoint(new S2Point(v))); @@ -93,7 +96,7 @@ void testSouthHemisphere() { double sinTol = FastMath.sin(tol); SphericalPolygonsSet south = new SphericalPolygonsSet(Vector3D.MINUS_K, tol); UnitSphereRandomVectorGenerator random = - new UnitSphereRandomVectorGenerator(3, new Well1024a(0x6b9d4a6ad90d7b0bl)); + new UnitSphereRandomVectorGenerator(3, new Well1024a(0x6b9d4a6ad90d7b0bL)); for (int i = 0; i < 1000; ++i) { Vector3D v = new Vector3D(random.nextVector()); if (v.getZ() < -sinTol) { @@ -111,7 +114,7 @@ void testSouthHemisphere() { assertEquals(0.5 * FastMath.PI, southCap.getRadius(), 1.0e-10); EnclosingBall northCap = - ((SphericalPolygonsSet) new RegionFactory().getComplement(south)).getEnclosingCap(); + ((SphericalPolygonsSet) new RegionFactory().getComplement(south)).getEnclosingCap(); assertEquals(0.0, S2Point.PLUS_K.distance(northCap.getCenter()), 1.0e-10); assertEquals(0.5 * FastMath.PI, northCap.getRadius(), 1.0e-10); @@ -121,14 +124,14 @@ void testSouthHemisphere() { void testPositiveOctantByIntersection() { double tol = 0.01; double sinTol = FastMath.sin(tol); - RegionFactory factory = new RegionFactory(); + RegionFactory factory = new RegionFactory<>(); SphericalPolygonsSet plusX = new SphericalPolygonsSet(Vector3D.PLUS_I, tol); SphericalPolygonsSet plusY = new SphericalPolygonsSet(Vector3D.PLUS_J, tol); SphericalPolygonsSet plusZ = new SphericalPolygonsSet(Vector3D.PLUS_K, tol); SphericalPolygonsSet octant = (SphericalPolygonsSet) factory.intersection(factory.intersection(plusX, plusY), plusZ); UnitSphereRandomVectorGenerator random = - new UnitSphereRandomVectorGenerator(3, new Well1024a(0x9c9802fde3cbcf25l)); + new UnitSphereRandomVectorGenerator(3, new Well1024a(0x9c9802fde3cbcf25L)); for (int i = 0; i < 1000; ++i) { Vector3D v = new Vector3D(random.nextVector()); if ((v.getX() > sinTol) && (v.getY() > sinTol) && (v.getZ() > sinTol)) { @@ -153,7 +156,7 @@ void testPositiveOctantByIntersection() { for (Vertex v = first; count == 0 || v != first; v = v.getOutgoing().getEnd()) { ++count; Edge e = v.getIncoming(); - assertTrue(v == e.getStart().getOutgoing().getEnd()); + assertSame(v, e.getStart().getOutgoing().getEnd()); xPFound = xPFound || e.getCircle().getPole().distance(Vector3D.PLUS_I) < 1.0e-10; yPFound = yPFound || e.getCircle().getPole().distance(Vector3D.PLUS_J) < 1.0e-10; zPFound = zPFound || e.getCircle().getPole().distance(Vector3D.PLUS_K) < 1.0e-10; @@ -170,9 +173,7 @@ void testPositiveOctantByIntersection() { assertTrue(zVFound); assertEquals(3, count); - assertEquals(0.0, - ((S2Point) octant.getBarycenter()).distance(new S2Point(new Vector3D(1, 1, 1))), - 1.0e-10); + assertEquals(0.0, octant.getBarycenter().distance(new S2Point(new Vector3D(1, 1, 1))), 1.0e-10); assertEquals(0.5 * FastMath.PI, octant.getSize(), 1.0e-10); EnclosingBall cap = octant.getEnclosingCap(); @@ -192,7 +193,7 @@ void testPositiveOctantByVertices() { double sinTol = FastMath.sin(tol); SphericalPolygonsSet octant = new SphericalPolygonsSet(tol, S2Point.PLUS_I, S2Point.PLUS_J, S2Point.PLUS_K); UnitSphereRandomVectorGenerator random = - new UnitSphereRandomVectorGenerator(3, new Well1024a(0xb8fc5acc91044308l)); + new UnitSphereRandomVectorGenerator(3, new Well1024a(0xb8fc5acc91044308L)); for (int i = 0; i < 1000; ++i) { Vector3D v = new Vector3D(random.nextVector()); if ((v.getX() > sinTol) && (v.getY() > sinTol) && (v.getZ() > sinTol)) { @@ -209,7 +210,7 @@ void testPositiveOctantByVertices() { void testNonConvex() { double tol = 0.01; double sinTol = FastMath.sin(tol); - RegionFactory factory = new RegionFactory(); + RegionFactory factory = new RegionFactory<>(); SphericalPolygonsSet plusX = new SphericalPolygonsSet(Vector3D.PLUS_I, tol); SphericalPolygonsSet plusY = new SphericalPolygonsSet(Vector3D.PLUS_J, tol); SphericalPolygonsSet plusZ = new SphericalPolygonsSet(Vector3D.PLUS_K, tol); @@ -217,7 +218,7 @@ void testNonConvex() { (SphericalPolygonsSet) factory.difference(plusZ, factory.intersection(plusX, plusY)); UnitSphereRandomVectorGenerator random = - new UnitSphereRandomVectorGenerator(3, new Well1024a(0x9c9802fde3cbcf25l)); + new UnitSphereRandomVectorGenerator(3, new Well1024a(0x9c9802fde3cbcf25L)); for (int i = 0; i < 1000; ++i) { Vector3D v = new Vector3D(random.nextVector()); if (((v.getX() < -sinTol) || (v.getY() < -sinTol)) && (v.getZ() > sinTol)) { @@ -245,7 +246,7 @@ void testNonConvex() { for (Vertex v = first; count == 0 || v != first; v = v.getOutgoing().getEnd()) { ++count; Edge e = v.getIncoming(); - assertTrue(v == e.getStart().getOutgoing().getEnd()); + assertSame(v, e.getStart().getOutgoing().getEnd()); if (e.getCircle().getPole().distance(Vector3D.MINUS_I) < 1.0e-10) { xPFound = true; sumPoleX += e.getLength(); @@ -278,7 +279,7 @@ void testNonConvex() { @Test void testModeratlyComplexShape() { double tol = 0.01; - List> boundary = new ArrayList>(); + List> boundary = new ArrayList<>(); boundary.add(create(Vector3D.MINUS_J, Vector3D.PLUS_I, Vector3D.PLUS_K, tol, 0.0, 0.5 * FastMath.PI)); boundary.add(create(Vector3D.MINUS_I, Vector3D.PLUS_K, Vector3D.PLUS_J, tol, 0.0, 0.5 * FastMath.PI)); boundary.add(create(Vector3D.PLUS_K, Vector3D.PLUS_J, Vector3D.MINUS_I, tol, 0.0, 0.5 * FastMath.PI)); @@ -312,7 +313,7 @@ void testModeratlyComplexShape() { for (Vertex v = first; count == 0 || v != first; v = v.getOutgoing().getEnd()) { ++count; Edge e = v.getIncoming(); - assertTrue(v == e.getStart().getOutgoing().getEnd()); + assertSame(v, e.getStart().getOutgoing().getEnd()); pXFound = pXFound || v.getLocation().getVector().distance(Vector3D.PLUS_I) < 1.0e-10; mXFound = mXFound || v.getLocation().getVector().distance(Vector3D.MINUS_I) < 1.0e-10; pYFound = pYFound || v.getLocation().getVector().distance(Vector3D.PLUS_J) < 1.0e-10; @@ -335,7 +336,7 @@ void testModeratlyComplexShape() { void testSeveralParts() { double tol = 0.01; double sinTol = FastMath.sin(tol); - List> boundary = new ArrayList>(); + List> boundary = new ArrayList<>(); // first part: +X, +Y, +Z octant boundary.add(create(Vector3D.PLUS_J, Vector3D.PLUS_K, Vector3D.PLUS_I, tol, 0.0, 0.5 * FastMath.PI)); @@ -350,7 +351,7 @@ void testSeveralParts() { SphericalPolygonsSet polygon = new SphericalPolygonsSet(boundary, tol); UnitSphereRandomVectorGenerator random = - new UnitSphereRandomVectorGenerator(3, new Well1024a(0xcc5ce49949e0d3ecl)); + new UnitSphereRandomVectorGenerator(3, new Well1024a(0xcc5ce49949e0d3ecL)); for (int i = 0; i < 1000; ++i) { Vector3D v = new Vector3D(random.nextVector()); if ((v.getX() < -sinTol) && (v.getY() < -sinTol) && (v.getZ() < -sinTol)) { @@ -385,7 +386,7 @@ void testPartWithHole() { new S2Point(FastMath.PI / 3, FastMath.PI / 3), new S2Point(FastMath.PI / 4, FastMath.PI / 6)); SphericalPolygonsSet hexaWithHole = - (SphericalPolygonsSet) new RegionFactory().difference(hexa, hole); + (SphericalPolygonsSet) new RegionFactory().difference(hexa, hole); for (double phi = center.getPhi() - alpha + 0.1; phi < center.getPhi() + alpha - 0.1; phi += 0.07) { Location l = hexaWithHole.checkPoint(new S2Point(FastMath.PI / 4, phi)); @@ -417,7 +418,7 @@ void testConcentricSubParts() { SphericalPolygonsSet triOut = new SphericalPolygonsSet(center, Vector3D.PLUS_K, 0.25, 3, tol); SphericalPolygonsSet triIn = new SphericalPolygonsSet(center, Vector3D.PLUS_K, 0.15, 3, tol); - RegionFactory factory = new RegionFactory(); + RegionFactory factory = new RegionFactory<>(); SphericalPolygonsSet hexa = (SphericalPolygonsSet) factory.difference(hexaOut, hexaIn); SphericalPolygonsSet penta = (SphericalPolygonsSet) factory.difference(pentaOut, pentaIn); SphericalPolygonsSet quadri = (SphericalPolygonsSet) factory.difference(quadriOut, quadriIn); @@ -478,10 +479,10 @@ void testGeographicalMap() { { 42.15249, 9.56001 }, { 43.00998, 9.39000 }, { 42.62812, 8.74600 }, { 42.25651, 8.54421 }, { 41.58361, 8.77572 }, { 41.38000, 9.22975 } }); - RegionFactory factory = new RegionFactory(); + RegionFactory factory = new RegionFactory<>(); SphericalPolygonsSet zone = (SphericalPolygonsSet) factory.union(continental, corsica); EnclosingBall enclosing = zone.getEnclosingCap(); - Vector3D enclosingCenter = ((S2Point) enclosing.getCenter()).getVector(); + Vector3D enclosingCenter = enclosing.getCenter().getVector(); double step = FastMath.toRadians(0.1); for (Vertex loopStart : zone.getBoundaryLoops()) { @@ -504,7 +505,7 @@ void testGeographicalMap() { EnclosingBall continentalInscribed = ((SphericalPolygonsSet) factory.getComplement(continental)).getEnclosingCap(); - Vector3D continentalCenter = ((S2Point) continentalInscribed.getCenter()).getVector(); + Vector3D continentalCenter = continentalInscribed.getCenter().getVector(); assertEquals(2.2, FastMath.toDegrees(FastMath.PI - continentalInscribed.getRadius()), 0.1); for (Vertex loopStart : continental.getBoundaryLoops()) { int count = 0; @@ -519,7 +520,7 @@ void testGeographicalMap() { EnclosingBall corsicaInscribed = ((SphericalPolygonsSet) factory.getComplement(corsica)).getEnclosingCap(); - Vector3D corsicaCenter = ((S2Point) corsicaInscribed.getCenter()).getVector(); + Vector3D corsicaCenter = corsicaInscribed.getCenter().getVector(); assertEquals(0.34, FastMath.toDegrees(FastMath.PI - corsicaInscribed.getRadius()), 0.01); for (Vertex loopStart : corsica.getBoundaryLoops()) { int count = 0; @@ -560,7 +561,7 @@ void testZigZagBoundary() { @Test void testGitHubIssue41() { - RegionFactory regionFactory = new RegionFactory<>(); + RegionFactory regionFactory = new RegionFactory<>(); S2Point[] s2pA = new S2Point[]{ new S2Point(new Vector3D(0.2122954606, -0.629606302, 0.7473463333)), new S2Point(new Vector3D(0.2120220248, -0.6296445493, 0.747391733)), @@ -594,15 +595,15 @@ void testGitHubIssue41() { @Test void testGitHubIssue42A() { // if building it was allowed (i.e. if the check for tolerance was removed) - // the BSP tree would wrong, it would include a large extra chunk that contains + // the BSP tree would be wrong, it would include a large extra chunk that contains // a point that should really be outside try { doTestGitHubIssue42(1.0e-100); } catch (MathIllegalArgumentException miae) { assertEquals(LocalizedGeometryFormats.TOO_SMALL_TOLERANCE, miae.getSpecifier()); - assertEquals(1.0e-100, ((Double) miae.getParts()[0]).doubleValue(), 1.0e-110); + assertEquals(1.0e-100, (Double) miae.getParts()[0], 1.0e-110); assertEquals("Sphere2D.SMALLEST_TOLERANCE", miae.getParts()[1]); - assertEquals(Sphere2D.SMALLEST_TOLERANCE, ((Double) miae.getParts()[2]).doubleValue(), 1.0e-20); + assertEquals(Sphere2D.SMALLEST_TOLERANCE, (Double) miae.getParts()[2], 1.0e-20); } } @@ -610,9 +611,8 @@ void testGitHubIssue42A() { void testGitHubIssue42B() { // the BSP tree is right, but size cannot be computed try { - /* success of this call is dependent on numerical noise. - * If it fails it should fail predictably. - */ + // success of this call is dependent on numerical noise. + // If it fails it should fail predictably. doTestGitHubIssue42(9.0e-16); } catch (MathIllegalStateException e) { assertEquals( @@ -697,7 +697,7 @@ void testZigZagBoundaryOversampledIssue46() { // check original points are on the boundary assertEquals(Location.BOUNDARY, zone.checkPoint(vertex), "" + vertex); double offset = FastMath.abs(zone.projectToBoundary(vertex).getOffset()); - assertEquals(0, offset, cornerTol, "" + vertex + " offset: " + offset); + assertEquals(0, offset, cornerTol, vertex + " offset: " + offset); // check original points are within the cap assertTrue( cap.contains(vertex, tol), @@ -728,7 +728,7 @@ void testPositiveOctantByVerticesDetailIssue46() { SphericalPolygonsSet octant = new SphericalPolygonsSet(tol, points.toArray(new S2Point[0])); UnitSphereRandomVectorGenerator random = - new UnitSphereRandomVectorGenerator(3, new Well1024a(0xb8fc5acc91044308l)); + new UnitSphereRandomVectorGenerator(3, new Well1024a(0xb8fc5acc91044308L)); /* Where exactly the boundaries fall depends on which points are kept from * decimation, which can vary by up to tol. So a point up to 2*tol away from a * input point may be on the boundary. All input points are guaranteed to be on @@ -851,7 +851,7 @@ void TestIntersectionOrder() { new S2Point(0.016, 1.5533430342749532) }; - final RegionFactory regionFactory = new RegionFactory(); + final RegionFactory regionFactory = new RegionFactory<>(); // thickness is small enough for proper computation of very small intersection double thickness1 = 4.96740426e-11; @@ -865,14 +865,126 @@ void TestIntersectionOrder() { final SphericalPolygonsSet sps3 = new SphericalPolygonsSet(thickness2, vertices1); final SphericalPolygonsSet sps4 = new SphericalPolygonsSet(thickness2, vertices2); assertEquals(1.4886e-12, regionFactory.intersection(sps3, sps4).getSize(), 1.0e-15); - assertEquals(2.4077e-06, regionFactory.intersection(sps4, sps3).getSize(), 1.0e-10); + assertEquals(0.0, regionFactory.intersection(sps4, sps3).getSize(), 1.0e-15); + + } + + @Test + public void testIssueOrekit1388A() { + doTestIssueOrekit1388(true); + } + + @Test + public void testIssueOrekit1388B() { + doTestIssueOrekit1388(false); + } + + private void doTestIssueOrekit1388(final boolean order) { + final double[][] coordinates1 = new double[][] { + { 18.52684751402596, -76.97880893719434 }, + { 18.451108862175584, -76.99484778988442 }, + { 18.375369256045143, -77.01087679277504 }, + { 18.299628701801268, -77.02689599675749 }, + { 18.223887203723567, -77.04290545732495 }, + { 18.148144771769385, -77.05890521550272 }, + { 18.072401410187016, -77.0748953260324 }, + { 17.99665712514784, -77.09087584010511 }, + { 17.92091192468999, -77.10684680260262 }, + { 17.84516581113023, -77.12280827309398 }, + { 17.769418792522664, -77.13876029654094 }, + { 17.747659863099422, -77.14334087084347 }, + { 17.67571798336192, -77.15846791369165 }, +// adding 1.0e-4 to the second coordinate of the following point +// generates an open outline boundary error + { 17.624293265977183, -77.16938381433733 }, + { 17.5485398681768, -77.18520934447962 }, + { 17.526779103104783, -77.1897823275402 }, + { 17.49650619905315, -77.0342031192472 }, + { 17.588661518962343, -77.01473903648854 }, + { 17.728574326965138, -76.98517769352242 }, + { 17.80416324015021, -76.96919708557023 }, + { 17.87969526622326, -76.95321858415689 }, + { 17.955280973332677, -76.93721874766547 }, + { 18.030855567607098, -76.92121123297645 }, + { 18.106414929680927, -76.90519686376611 }, + { 18.182031502555215, -76.88916022728444 }, + { 18.257597934434987, -76.87312403715188 }, + { 18.3331742522667, -76.85707550881591 }, + { 18.408750874895002, -76.84101662269072 }, + { 18.57249082100609, -76.80620195239239 }, + { 18.602585205425896, -76.96276018365842 } + }; + + final double[][] coordinates2 = new double[][] { + { 18.338614038907608, -78.37885677406668 }, + { 18.195574802144037, -78.24425107003432 }, + { 18.20775293886321, -78.0711865934217 }, + { 18.07679345301507, -77.95901517339438 }, + { 18.006705181057598, -77.85325354879791 }, + { 17.857293838883137, -77.73787723105598 }, + { 17.854243316622103, -77.57442744758828 }, + { 17.875595873376014, -77.38213358468467 }, + { 17.72607423578937, -77.23470828979222 }, + { 17.71386286451302, -77.12253686976543 }, + { 17.790170276013725, -77.14817605148616 }, + { 17.869495404611797, -77.14497115377101 }, + { 17.854243309397717, -76.9302429967729 }, + { 17.954882874700132, -76.84371075846688 }, + { 17.94268718313505, -76.6898756681441 }, + { 17.869495397388064, -76.54886016868198 }, + { 17.863394719203555, -76.35015651034861 }, + { 17.93049065091843, -76.23478019260665 }, + { 18.155989976776553, -76.32451732862788 }, + { 18.22601854027039, -76.63218750927341 }, + { 18.33861403170316, -76.85653034932697 }, + { 18.405527980074993, -76.97831646249921 }, + { 18.4541763474828, -77.28598664314421 }, + { 18.496732365966466, -77.705828243816 }, + { 18.451136227912485, -78.00708862903122 }, + { 18.405527980074993, -78.25707065080552 } + }; + + final double[][] expectedIn = new double[][] { + { 18.408, -77.003 }, + { 18.338, -76.857 }, + { 17.869, -77.117 }, + { 17.857, -76.959 }, + { 17.761, -77.139 }, + { 17.715, -77.125 }, + { 17.935, -77.055 } + }; + + final double[][] expectedOut = new double[][] { + { 17.794, -77.145 }, + { 17.736, -76.981 }, + { 17.715, -77.138 }, + { 18.153, -77.059 }, + { 18.232, -76.877 }, + { 18.373, -76.917 }, + { 17.871, -77.261 } // this is the point that was wrongly inside the intersection + }; + + SphericalPolygonsSet shape1 = buildSimpleZone(coordinates1); + SphericalPolygonsSet shape2 = buildSimpleZone(coordinates2); + Region intersection = + order ? + new RegionFactory().intersection(shape1.copySelf(), shape2.copySelf()) : + new RegionFactory().intersection(shape2.copySelf(), shape1.copySelf()); + + for (final double[] doubles : expectedIn) { + Assertions.assertEquals(Location.INSIDE, intersection.checkPoint(s2Point(doubles[0], doubles[1]))); + } + + for (final double[] doubles : expectedOut) { + Assertions.assertEquals(Location.OUTSIDE, intersection.checkPoint(s2Point(doubles[0], doubles[1]))); + } } private SubCircle create(Vector3D pole, Vector3D x, Vector3D y, double tolerance, double ... limits) { - RegionFactory factory = new RegionFactory(); - Circle circle = new Circle(pole, tolerance); + RegionFactory factory = new RegionFactory<>(); + Circle circle = new Circle(pole, tolerance); Circle phased = (Circle) Circle.getTransform(new Rotation(circle.getXAxis(), circle.getYAxis(), x, y)).apply(circle); ArcsSet set = (ArcsSet) factory.getComplement(new ArcsSet(tolerance)); diff --git a/hipparchus-geometry/src/test/java/org/hipparchus/geometry/spherical/twod/SubCircleTest.java b/hipparchus-geometry/src/test/java/org/hipparchus/geometry/spherical/twod/SubCircleTest.java index 57af7b98c..a1529b0c4 100644 --- a/hipparchus-geometry/src/test/java/org/hipparchus/geometry/spherical/twod/SubCircleTest.java +++ b/hipparchus-geometry/src/test/java/org/hipparchus/geometry/spherical/twod/SubCircleTest.java @@ -27,14 +27,16 @@ import org.hipparchus.geometry.partitioning.Side; import org.hipparchus.geometry.partitioning.SubHyperplane.SplitSubHyperplane; import org.hipparchus.geometry.spherical.oned.ArcsSet; +import org.hipparchus.geometry.spherical.oned.S1Point; import org.hipparchus.geometry.spherical.oned.Sphere1D; import org.hipparchus.util.MathUtils; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNotSame; import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertSame; class SubCircleTest { @@ -43,8 +45,8 @@ void testFullCircle() { Circle circle = new Circle(Vector3D.PLUS_K, 1.0e-10); SubCircle set = circle.wholeHyperplane(); assertEquals(MathUtils.TWO_PI, set.getSize(), 1.0e-10); - assertTrue(circle == set.getHyperplane()); - assertTrue(circle != set.copySelf().getHyperplane()); + assertSame(circle, set.getHyperplane()); + assertNotSame(circle, set.copySelf().getHyperplane()); } @Test @@ -75,7 +77,7 @@ void testSPlit() { Circle xzPlane = new Circle(Vector3D.PLUS_J, 1.0e-10); SubCircle sc1 = create(Vector3D.PLUS_K, Vector3D.PLUS_I, Vector3D.PLUS_J, 1.0e-10, 1.0, 3.0, 5.0, 6.0); - SplitSubHyperplane split1 = sc1.split(xzPlane); + SplitSubHyperplane split1 = sc1.split(xzPlane); ArcsSet plus1 = (ArcsSet) ((SubCircle) split1.getPlus()).getRemainingRegion(); ArcsSet minus1 = (ArcsSet) ((SubCircle) split1.getMinus()).getRemainingRegion(); assertEquals(1, plus1.asList().size()); @@ -86,7 +88,7 @@ void testSPlit() { assertEquals(3.0, minus1.asList().get(0).getSup(), 1.0e-10); SubCircle sc2 = create(Vector3D.PLUS_K, Vector3D.PLUS_I, Vector3D.PLUS_J, 1.0e-10, 1.0, 3.0); - SplitSubHyperplane split2 = sc2.split(xzPlane); + SplitSubHyperplane split2 = sc2.split(xzPlane); assertNull(split2.getPlus()); ArcsSet minus2 = (ArcsSet) ((SubCircle) split2.getMinus()).getRemainingRegion(); assertEquals(1, minus2.asList().size()); @@ -94,7 +96,7 @@ void testSPlit() { assertEquals(3.0, minus2.asList().get(0).getSup(), 1.0e-10); SubCircle sc3 = create(Vector3D.PLUS_K, Vector3D.PLUS_I, Vector3D.PLUS_J, 1.0e-10, 5.0, 6.0); - SplitSubHyperplane split3 = sc3.split(xzPlane); + SplitSubHyperplane split3 = sc3.split(xzPlane); ArcsSet plus3 = (ArcsSet) ((SubCircle) split3.getPlus()).getRemainingRegion(); assertEquals(1, plus3.asList().size()); assertEquals(5.0, plus3.asList().get(0).getInf(), 1.0e-10); @@ -102,13 +104,13 @@ void testSPlit() { assertNull(split3.getMinus()); SubCircle sc4 = create(Vector3D.PLUS_J, Vector3D.PLUS_K, Vector3D.PLUS_I, 1.0e-10, 5.0, 6.0); - SplitSubHyperplane split4 = sc4.split(xzPlane); + SplitSubHyperplane split4 = sc4.split(xzPlane); assertEquals(Side.HYPER, sc4.split(xzPlane).getSide()); assertNull(split4.getPlus()); assertNull(split4.getMinus()); SubCircle sc5 = create(Vector3D.MINUS_J, Vector3D.PLUS_I, Vector3D.PLUS_K, 1.0e-10, 5.0, 6.0); - SplitSubHyperplane split5 = sc5.split(xzPlane); + SplitSubHyperplane split5 = sc5.split(xzPlane); assertEquals(Side.HYPER, sc5.split(xzPlane).getSide()); assertNull(split5.getPlus()); assertNull(split5.getMinus()); @@ -124,7 +126,7 @@ void testSideSplitConsistency() { SubCircle sub = new SubCircle(new Circle(new Vector3D(2.1793884139073498E-4, 0.9790647032675541, -0.20354915700704285), tolerance), new ArcsSet(4.7121441684170700, 4.7125386635004760, tolerance)); - SplitSubHyperplane split = sub.split(hyperplane); + SplitSubHyperplane split = sub.split(hyperplane); assertNotNull(split.getMinus()); assertNull(split.getPlus()); assertEquals(Side.MINUS, sub.split(hyperplane).getSide()); @@ -133,8 +135,8 @@ void testSideSplitConsistency() { private SubCircle create(Vector3D pole, Vector3D x, Vector3D y, double tolerance, double ... limits) { - RegionFactory factory = new RegionFactory(); - Circle circle = new Circle(pole, tolerance); + RegionFactory factory = new RegionFactory<>(); + Circle circle = new Circle(pole, tolerance); Circle phased = (Circle) Circle.getTransform(new Rotation(circle.getXAxis(), circle.getYAxis(), x, y)).apply(circle); ArcsSet set = (ArcsSet) factory.getComplement(new ArcsSet(tolerance)); diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 95df3508e..d1d77ff47 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -50,6 +50,12 @@ If the output is not quite correct, check for invisible trailing spaces! + + Added point type to geometry classes parameters + + + Improved robustness of BSP tree operations + Rename DEFAULT_MAXCHECK as DEFAULT_MAX_CHECK.