EdgesWithNodeInfoBuilder.java

  1. /*
  2.  * Licensed to the Hipparchus project under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The Hipparchus project licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      https://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.hipparchus.geometry.spherical.twod;

  18. import java.util.ArrayList;
  19. import java.util.List;

  20. import org.hipparchus.geometry.partitioning.BSPTree;
  21. import org.hipparchus.geometry.partitioning.BSPTreeVisitor;
  22. import org.hipparchus.geometry.partitioning.BoundaryAttribute;
  23. import org.hipparchus.geometry.spherical.oned.Arc;
  24. import org.hipparchus.geometry.spherical.oned.ArcsSet;
  25. import org.hipparchus.geometry.spherical.oned.S1Point;
  26. import org.hipparchus.util.FastMath;

  27. /** Visitor building edges.
  28.  * @since 1.4
  29.  */
  30. class EdgesWithNodeInfoBuilder implements BSPTreeVisitor<Sphere2D, S2Point, Circle, SubCircle> {

  31.     /** Tolerance for close nodes connection. */
  32.     private final double tolerance;

  33.     /** Built segments. */
  34.     private final List<EdgeWithNodeInfo> edges;

  35.     /** Simple constructor.
  36.      * @param tolerance below which points are consider to be identical
  37.      */
  38.     EdgesWithNodeInfoBuilder(final double tolerance) {
  39.         this.tolerance = tolerance;
  40.         this.edges     = new ArrayList<>();
  41.     }

  42.     /** {@inheritDoc} */
  43.     @Override
  44.     public Order visitOrder(final BSPTree<Sphere2D, S2Point, Circle, SubCircle> node) {
  45.         return Order.MINUS_SUB_PLUS;
  46.     }

  47.     /** {@inheritDoc} */
  48.     @Override
  49.     public void visitInternalNode(final BSPTree<Sphere2D, S2Point, Circle, SubCircle> node) {
  50.         @SuppressWarnings("unchecked")
  51.         final BoundaryAttribute<Sphere2D, S2Point, Circle, SubCircle> attribute =
  52.                 (BoundaryAttribute<Sphere2D, S2Point, Circle, SubCircle>) node.getAttribute();
  53.         final Iterable<BSPTree<Sphere2D, S2Point, Circle, SubCircle>> splitters = attribute.getSplitters();
  54.         if (attribute.getPlusOutside() != null) {
  55.             addContribution(attribute.getPlusOutside(), node, splitters, false);
  56.         }
  57.         if (attribute.getPlusInside() != null) {
  58.             addContribution(attribute.getPlusInside(), node, splitters, true);
  59.         }
  60.     }

  61.     /** {@inheritDoc} */
  62.     @Override
  63.     public void visitLeafNode(final BSPTree<Sphere2D, S2Point, Circle, SubCircle> node) {
  64.     }

  65.     /** Add the contribution of a boundary edge.
  66.      * @param sub boundary facet
  67.      * @param node node to which the edge belongs
  68.      * @param splitters splitters for the boundary facet
  69.      * @param reversed if true, the facet has the inside on its plus side
  70.      */
  71.     private void addContribution(final SubCircle sub, final BSPTree<Sphere2D, S2Point, Circle, SubCircle> node,
  72.                                  final Iterable<BSPTree<Sphere2D, S2Point, Circle, SubCircle>> splitters,
  73.                                  final boolean reversed) {
  74.         final Circle circle  = sub.getHyperplane();
  75.         final List<Arc> arcs = ((ArcsSet) sub.getRemainingRegion()).asList();
  76.         for (final Arc a : arcs) {

  77.             // find the 2D points
  78.             final Vertex startS = new Vertex(circle.toSpace(new S1Point(a.getInf())));
  79.             final Vertex endS   = new Vertex(circle.toSpace(new S1Point(a.getSup())));

  80.             // recover the connectivity information
  81.             final BSPTree<Sphere2D, S2Point, Circle, SubCircle> startN = selectClosest(startS.getLocation(), splitters);
  82.             final BSPTree<Sphere2D, S2Point, Circle, SubCircle> endN   = selectClosest(endS.getLocation(), splitters);

  83.             if (reversed) {
  84.                 edges.add(new EdgeWithNodeInfo(endS, startS, a.getSize(), circle.getReverse(), node, endN, startN));
  85.             } else {
  86.                 edges.add(new EdgeWithNodeInfo(startS, endS, a.getSize(), circle, node, startN, endN));
  87.             }

  88.         }
  89.     }

  90.     /** Select the node whose cut sub-hyperplane is closest to specified point.
  91.      * @param point reference point
  92.      * @param candidates candidate nodes
  93.      * @return node closest to point, or null if no node is closer than tolerance
  94.      */
  95.     private BSPTree<Sphere2D, S2Point, Circle, SubCircle>
  96.         selectClosest(final S2Point point, final Iterable<BSPTree<Sphere2D, S2Point, Circle, SubCircle>> candidates) {

  97.         if (point == null) {
  98.             return null;
  99.         }

  100.         BSPTree<Sphere2D, S2Point, Circle, SubCircle> selected = null;

  101.         double min = Double.POSITIVE_INFINITY;
  102.         for (final BSPTree<Sphere2D, S2Point, Circle, SubCircle> node : candidates) {
  103.             final double distance = FastMath.abs(node.getCut().getHyperplane().getOffset(point));
  104.             if (distance < min) {
  105.                 selected = node;
  106.                 min      = distance;
  107.             }
  108.         }

  109.         return min <= tolerance ? selected : null;

  110.     }

  111.     /** Get the edges.
  112.      * @return built edges
  113.      */
  114.     public List<EdgeWithNodeInfo> getEdges() {
  115.         return edges;
  116.     }

  117. }