View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) 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 ASF 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  
18  /*
19   * This is not the original file distributed by the Apache Software Foundation
20   * It has been modified by the Hipparchus project
21   */
22  package org.hipparchus.geometry.partitioning;
23  
24  import java.util.Formatter;
25  import java.util.Locale;
26  
27  import org.hipparchus.geometry.Space;
28  import org.hipparchus.geometry.euclidean.oned.Euclidean1D;
29  import org.hipparchus.geometry.euclidean.oned.IntervalsSet;
30  import org.hipparchus.geometry.euclidean.oned.OrientedPoint;
31  import org.hipparchus.geometry.euclidean.oned.Vector1D;
32  import org.hipparchus.geometry.euclidean.threed.Euclidean3D;
33  import org.hipparchus.geometry.euclidean.threed.Plane;
34  import org.hipparchus.geometry.euclidean.threed.PolyhedronsSet;
35  import org.hipparchus.geometry.euclidean.threed.Vector3D;
36  import org.hipparchus.geometry.euclidean.twod.Euclidean2D;
37  import org.hipparchus.geometry.euclidean.twod.Line;
38  import org.hipparchus.geometry.euclidean.twod.PolygonsSet;
39  import org.hipparchus.geometry.euclidean.twod.Vector2D;
40  import org.hipparchus.geometry.spherical.oned.ArcsSet;
41  import org.hipparchus.geometry.spherical.oned.LimitAngle;
42  import org.hipparchus.geometry.spherical.oned.Sphere1D;
43  import org.hipparchus.geometry.spherical.twod.Circle;
44  import org.hipparchus.geometry.spherical.twod.Sphere2D;
45  import org.hipparchus.geometry.spherical.twod.SphericalPolygonsSet;
46  
47  /** Class dumping a string representation of an {@link AbstractRegion}.
48   * <p>
49   * This class is intended for tests and debug purposes only.
50   * </p>
51   * @see RegionParser
52   */
53  public class RegionDumper {
54  
55      /** Private constructor for a utility class
56       */
57      private RegionDumper() {
58      }
59  
60      /** Get a string representation of an {@link ArcsSet}.
61       * @param arcsSet region to dump
62       * @return string representation of the region
63       */
64      public static String dump(final ArcsSet arcsSet) {
65          final TreeDumper<Sphere1D> visitor = new TreeDumper<Sphere1D>("ArcsSet", arcsSet.getTolerance()) {
66  
67              /** {@inheritDoc} */
68              @Override
69              protected void formatHyperplane(final Hyperplane<Sphere1D> hyperplane) {
70                  final LimitAngle h = (LimitAngle) hyperplane;
71                  getFormatter().format("%22.15e %b %22.15e",
72                                        h.getLocation().getAlpha(), h.isDirect(), h.getTolerance());
73              }
74  
75          };
76          arcsSet.getTree(false).visit(visitor);
77          return visitor.getDump();
78      }
79  
80      /** Get a string representation of a {@link SphericalPolygonsSet}.
81       * @param sphericalPolygonsSet region to dump
82       * @return string representation of the region
83       */
84      public static String dump(final SphericalPolygonsSet sphericalPolygonsSet) {
85          final TreeDumper<Sphere2D> visitor = new TreeDumper<Sphere2D>("SphericalPolygonsSet", sphericalPolygonsSet.getTolerance()) {
86  
87              /** {@inheritDoc} */
88              @Override
89              protected void formatHyperplane(final Hyperplane<Sphere2D> hyperplane) {
90                  final Circle h = (Circle) hyperplane;
91                  getFormatter().format("%22.15e %22.15e %22.15e %22.15e",
92                                        h.getPole().getX(), h.getPole().getY(), h.getPole().getZ(),
93                                        h.getTolerance());
94              }
95  
96          };
97          sphericalPolygonsSet.getTree(false).visit(visitor);
98          return visitor.getDump();
99      }
100 
101     /** Get a string representation of an {@link IntervalsSet}.
102      * @param intervalsSet region to dump
103      * @return string representation of the region
104      */
105     public static String dump(final IntervalsSet intervalsSet) {
106         final TreeDumper<Euclidean1D> visitor = new TreeDumper<Euclidean1D>("IntervalsSet", intervalsSet.getTolerance()) {
107 
108             /** {@inheritDoc} */
109             @Override
110             protected void formatHyperplane(final Hyperplane<Euclidean1D> hyperplane) {
111                 final OrientedPoint h = (OrientedPoint) hyperplane;
112                 getFormatter().format("%22.15e %b %22.15e",
113                                       h.getLocation().getX(), h.isDirect(), h.getTolerance());
114             }
115 
116         };
117         intervalsSet.getTree(false).visit(visitor);
118         return visitor.getDump();
119     }
120 
121     /** Get a string representation of a {@link PolygonsSet}.
122      * @param polygonsSet region to dump
123      * @return string representation of the region
124      */
125     public static String dump(final PolygonsSet polygonsSet) {
126         final TreeDumper<Euclidean2D> visitor = new TreeDumper<Euclidean2D>("PolygonsSet", polygonsSet.getTolerance()) {
127 
128             /** {@inheritDoc} */
129             @Override
130             protected void formatHyperplane(final Hyperplane<Euclidean2D> hyperplane) {
131                 final Line h = (Line) hyperplane;
132                 final Vector2D p = h.toSpace(Vector1D.ZERO);
133                 getFormatter().format("%22.15e %22.15e %22.15e %22.15e",
134                                       p.getX(), p.getY(), h.getAngle(), h.getTolerance());
135             }
136 
137         };
138         polygonsSet.getTree(false).visit(visitor);
139         return visitor.getDump();
140     }
141 
142     /** Get a string representation of a {@link PolyhedronsSet}.
143      * @param polyhedronsSet region to dump
144      * @return string representation of the region
145      */
146     public static String dump(final PolyhedronsSet polyhedronsSet) {
147         final TreeDumper<Euclidean3D> visitor = new TreeDumper<Euclidean3D>("PolyhedronsSet", polyhedronsSet.getTolerance()) {
148 
149             /** {@inheritDoc} */
150             @Override
151             protected void formatHyperplane(final Hyperplane<Euclidean3D> hyperplane) {
152                 final Plane h = (Plane) hyperplane;
153                 final Vector3D p = h.toSpace(Vector2D.ZERO);
154                 getFormatter().format("%22.15e %22.15e %22.15e %22.15e %22.15e %22.15e %22.15e",
155                                       p.getX(), p.getY(), p.getZ(),
156                                       h.getNormal().getX(), h.getNormal().getY(), h.getNormal().getZ(),
157                                       h.getTolerance());
158             }
159 
160         };
161         polyhedronsSet.getTree(false).visit(visitor);
162         return visitor.getDump();
163     }
164 
165     /** Dumping visitor.
166      * @param <S> Type of the space.
167      */
168     private abstract static class TreeDumper<S extends Space> implements BSPTreeVisitor<S> {
169 
170         /** Builder for the string representation of the dumped tree. */
171         private final StringBuilder dump;
172 
173         /** Formatter for strings. */
174         private final Formatter formatter;
175 
176         /** Current indentation prefix. */
177         private String prefix;
178 
179         /** Simple constructor.
180          * @param type type of the region to dump
181          * @param tolerance tolerance of the region
182          */
183         public TreeDumper(final String type, final double tolerance) {
184             this.dump      = new StringBuilder();
185             this.formatter = new Formatter(dump, Locale.US);
186             this.prefix    = "";
187             formatter.format("%s%n", type);
188             formatter.format("tolerance %22.15e%n", tolerance);
189         }
190 
191         /** Get the string representation of the tree.
192          * @return string representation of the tree.
193          */
194         public String getDump() {
195             return dump.toString();
196         }
197 
198         /** Get the formatter to use.
199          * @return formatter to use
200          */
201         protected Formatter getFormatter() {
202             return formatter;
203         }
204 
205         /** Format a string representation of the hyperplane underlying a cut sub-hyperplane.
206          * @param hyperplane hyperplane to format
207          */
208         protected abstract void formatHyperplane(Hyperplane<S> hyperplane);
209 
210         /** {@inheritDoc} */
211         @Override
212         public Order visitOrder(final BSPTree<S> node) {
213             return Order.SUB_MINUS_PLUS;
214         }
215 
216         /** {@inheritDoc} */
217         @Override
218         public void visitInternalNode(final BSPTree<S> node) {
219             formatter.format("%s %s internal ", prefix, type(node));
220             formatHyperplane(node.getCut().getHyperplane());
221             formatter.format("%n");
222             prefix = prefix + "  ";
223         }
224 
225         /** {@inheritDoc} */
226         @Override
227         public void visitLeafNode(final BSPTree<S> node) {
228             formatter.format("%s %s leaf %s%n",
229                              prefix, type(node), node.getAttribute());
230             for (BSPTree<S> n = node;
231                  n.getParent() != null && n == n.getParent().getPlus();
232                  n = n.getParent()) {
233                 prefix = prefix.substring(0, prefix.length() - 2);
234             }
235         }
236 
237         /** Get the type of the node.
238          * @param node node to check
239          * @return "plus " or "minus" depending on the node being the plus or minus
240          * child of its parent ("plus " is arbitrarily returned for the root node)
241          */
242         private String type(final BSPTree<S> node) {
243             return (node.getParent() != null && node == node.getParent().getMinus()) ? "minus" : "plus ";
244         }
245 
246     }
247 
248 }