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