1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  package org.hipparchus.geometry.partitioning;
23  
24  import java.io.IOException;
25  import java.text.ParseException;
26  import java.util.StringTokenizer;
27  
28  import org.hipparchus.geometry.Point;
29  import org.hipparchus.geometry.Space;
30  import org.hipparchus.geometry.euclidean.oned.Euclidean1D;
31  import org.hipparchus.geometry.euclidean.oned.IntervalsSet;
32  import org.hipparchus.geometry.euclidean.oned.OrientedPoint;
33  import org.hipparchus.geometry.euclidean.oned.SubOrientedPoint;
34  import org.hipparchus.geometry.euclidean.oned.Vector1D;
35  import org.hipparchus.geometry.euclidean.threed.Euclidean3D;
36  import org.hipparchus.geometry.euclidean.threed.Plane;
37  import org.hipparchus.geometry.euclidean.threed.PolyhedronsSet;
38  import org.hipparchus.geometry.euclidean.threed.SubPlane;
39  import org.hipparchus.geometry.euclidean.threed.Vector3D;
40  import org.hipparchus.geometry.euclidean.twod.Euclidean2D;
41  import org.hipparchus.geometry.euclidean.twod.Line;
42  import org.hipparchus.geometry.euclidean.twod.PolygonsSet;
43  import org.hipparchus.geometry.euclidean.twod.SubLine;
44  import org.hipparchus.geometry.euclidean.twod.Vector2D;
45  import org.hipparchus.geometry.spherical.oned.ArcsSet;
46  import org.hipparchus.geometry.spherical.oned.LimitAngle;
47  import org.hipparchus.geometry.spherical.oned.S1Point;
48  import org.hipparchus.geometry.spherical.oned.Sphere1D;
49  import org.hipparchus.geometry.spherical.oned.SubLimitAngle;
50  import org.hipparchus.geometry.spherical.twod.Circle;
51  import org.hipparchus.geometry.spherical.twod.S2Point;
52  import org.hipparchus.geometry.spherical.twod.Sphere2D;
53  import org.hipparchus.geometry.spherical.twod.SphericalPolygonsSet;
54  import org.hipparchus.geometry.spherical.twod.SubCircle;
55  
56  
57  
58  
59  
60  
61  
62  public class RegionParser {
63  
64      
65  
66      private RegionParser() {
67      }
68  
69      
70  
71  
72  
73  
74  
75      public static ArcsSet parseArcsSet(final String s)
76          throws IOException, ParseException {
77          final TreeBuilder<Sphere1D, S1Point, LimitAngle, SubLimitAngle> builder =
78                  new TreeBuilder<Sphere1D, S1Point, LimitAngle, SubLimitAngle>("ArcsSet", s) {
79  
80              
81              @Override
82              protected LimitAngle parseHyperplane() throws ParseException {
83                  return new LimitAngle(new S1Point(getNumber()), getBoolean(), getNumber());
84              }
85  
86          };
87          return new ArcsSet(builder.getTree(), builder.getTolerance());
88      }
89  
90      
91  
92  
93  
94  
95  
96      public static SphericalPolygonsSet parseSphericalPolygonsSet(final String s)
97          throws IOException, ParseException {
98          final TreeBuilder<Sphere2D, S2Point, Circle, SubCircle> builder =
99                  new TreeBuilder<Sphere2D, S2Point, Circle, SubCircle>("SphericalPolygonsSet", s) {
100 
101             
102             @Override
103             public Circle parseHyperplane() {
104                 return new Circle(new Vector3D(getNumber(), getNumber(), getNumber()), getNumber());
105             }
106 
107         };
108         return new SphericalPolygonsSet(builder.getTree(), builder.getTolerance());
109     }
110 
111     
112 
113 
114 
115 
116 
117     public static IntervalsSet parseIntervalsSet(final String s)
118         throws IOException, ParseException {
119         final TreeBuilder<Euclidean1D, Vector1D, OrientedPoint, SubOrientedPoint> builder =
120                 new TreeBuilder<Euclidean1D, Vector1D, OrientedPoint, SubOrientedPoint>("IntervalsSet", s) {
121 
122             
123             @Override
124             public OrientedPoint parseHyperplane() throws ParseException {
125                 return new OrientedPoint(new Vector1D(getNumber()), getBoolean(), getNumber());
126             }
127 
128         };
129         return new IntervalsSet(builder.getTree(), builder.getTolerance());
130     }
131 
132     
133 
134 
135 
136 
137 
138     public static PolygonsSet parsePolygonsSet(final String s)
139         throws IOException, ParseException {
140         final TreeBuilder<Euclidean2D, Vector2D, Line, SubLine> builder =
141                 new TreeBuilder<Euclidean2D, Vector2D, Line, SubLine>("PolygonsSet", s) {
142 
143             
144             @Override
145             public Line parseHyperplane() {
146                 return new Line(new Vector2D(getNumber(), getNumber()), getNumber(), getNumber());
147             }
148 
149         };
150         return new PolygonsSet(builder.getTree(), builder.getTolerance());
151     }
152 
153     
154 
155 
156 
157 
158 
159     public static PolyhedronsSet parsePolyhedronsSet(final String s)
160         throws IOException, ParseException {
161         final TreeBuilder<Euclidean3D, Vector3D, Plane, SubPlane> builder =
162                 new TreeBuilder<Euclidean3D, Vector3D, Plane, SubPlane>("PolyhedronsSet", s) {
163 
164             
165             @Override
166             public Plane parseHyperplane() {
167                 return new Plane(new Vector3D(getNumber(), getNumber(), getNumber()),
168                                  new Vector3D(getNumber(), getNumber(), getNumber()),
169                                  getNumber());
170             }
171 
172         };
173         return new PolyhedronsSet(builder.getTree(), builder.getTolerance());
174     }
175 
176     
177 
178 
179 
180 
181 
182     private abstract static class TreeBuilder<S extends Space,
183                                               P extends Point<S, P>,
184                                               H extends Hyperplane<S, P, H, I>,
185                                               I extends SubHyperplane<S, P, H, I>> {
186 
187         
188         private static final String TOLERANCE = "tolerance";
189 
190         
191         private static final String INTERNAL  = "internal";
192 
193         
194         private static final String LEAF      = "leaf";
195 
196         
197         private static final String PLUS      = "plus";
198 
199         
200         private static final String MINUS     = "minus";
201 
202         
203         private static final String TRUE      = "true";
204 
205         
206         private static final String FALSE     = "false";
207 
208         
209         private BSPTree<S, P, H, I> root;
210 
211         
212         private final double tolerance;
213 
214         
215         private final StringTokenizer tokenizer;
216 
217         
218 
219 
220 
221 
222 
223         public TreeBuilder(final String type, final String s)
224             throws IOException, ParseException {
225             root = null;
226             tokenizer = new StringTokenizer(s);
227             getWord(type);
228             getWord(TOLERANCE);
229             tolerance = getNumber();
230             getWord(PLUS);
231             root = new BSPTree<>();
232             parseTree(root);
233             if (tokenizer.hasMoreTokens()) {
234                 throw new ParseException("unexpected " + tokenizer.nextToken(), 0);
235             }
236         }
237 
238         
239 
240 
241 
242 
243         private void parseTree(final BSPTree<S, P, H, I> node)
244             throws IOException, ParseException {
245             if (INTERNAL.equals(getWord(INTERNAL, LEAF))) {
246                 
247                 
248                 node.insertCut(parseHyperplane());
249                 getWord(MINUS);
250                 parseTree(node.getMinus());
251                 getWord(PLUS);
252                 parseTree(node.getPlus());
253             } else {
254                 
255                 node.setAttribute(getBoolean());
256             }
257         }
258 
259         
260 
261 
262 
263 
264         protected String getWord(final String ... allowed) throws ParseException {
265             final String token = tokenizer.nextToken();
266             for (final String a : allowed) {
267                 if (a.equals(token)) {
268                     return token;
269                 }
270             }
271             throw new ParseException(token + " != " + allowed[0], 0);
272         }
273 
274         
275 
276 
277 
278         protected double getNumber() throws NumberFormatException {
279             return Double.parseDouble(tokenizer.nextToken());
280         }
281 
282         
283 
284 
285 
286         protected boolean getBoolean() throws ParseException {
287             return getWord(TRUE, FALSE).equals(TRUE);
288         }
289 
290         
291 
292 
293         public BSPTree<S, P, H, I> getTree() {
294             return root;
295         }
296 
297         
298 
299 
300         public double getTolerance() {
301             return tolerance;
302         }
303 
304         
305 
306 
307 
308 
309         protected abstract H parseHyperplane()
310             throws IOException, ParseException;
311 
312     }
313 
314 }