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    *      http://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.apache.commons.geometry.examples.tutorials.bsp;
18  
19  import java.io.File;
20  import java.util.Arrays;
21  import java.util.HashMap;
22  import java.util.Map;
23  
24  import org.apache.commons.geometry.core.precision.DoublePrecisionContext;
25  import org.apache.commons.geometry.core.precision.EpsilonDoublePrecisionContext;
26  import org.apache.commons.geometry.euclidean.twod.Bounds2D;
27  import org.apache.commons.geometry.euclidean.twod.Lines;
28  import org.apache.commons.geometry.euclidean.twod.RegionBSPTree2D;
29  import org.apache.commons.geometry.euclidean.twod.RegionBSPTree2D.RegionNode2D;
30  import org.apache.commons.geometry.euclidean.twod.Segment;
31  import org.apache.commons.geometry.euclidean.twod.Vector2D;
32  import org.apache.commons.geometry.euclidean.twod.path.LinePath;
33  
34  /** Class containing tutorial code for constructing a 2D BSP tree using
35   * a top-down approach.
36   */
37  public final class TopDownBSPTreeConstruction {
38  
39      /** String defining the name format of output svg files. */
40      private static final String OUTPUT_FILE_FORMAT = "td-cut-%d.svg";
41  
42      /** No instantiation. */
43      private TopDownBSPTreeConstruction() {}
44  
45      /** Tutorial code entry point.
46       * @param args command arguments; if given, the first argument is used as the location of
47       *      output folder
48       */
49      public static void main(String[] args) {
50          File outputFolder = new File(args.length > 0 ? args[0] : ".");
51          BSPTreeSVGWriter svgWriter = new BSPTreeSVGWriter(Bounds2D.from(Vector2D.of(-8, -8), Vector2D.of(8, 8)));
52  
53          Map<RegionNode2D, String> nodeNames = new HashMap<>();
54          int cutCount = 0;
55  
56          // create a precision context for floating point comparisons
57          DoublePrecisionContext precision = new EpsilonDoublePrecisionContext(1e-6);
58  
59          // construct an empty tree
60          RegionBSPTree2D tree = RegionBSPTree2D.empty();
61  
62          Segment firstBoundary = Lines.segmentFromPoints(Vector2D.of(-5, 0), Vector2D.of(-1, 0), precision);
63          tree.insert(firstBoundary);
64  
65          RegionNode2D a = tree.getRoot();
66          RegionNode2D b = a.getMinus();
67          RegionNode2D c = a.getPlus();
68  
69          nodeNames.put(a, "a");
70          nodeNames.put(b, "b");
71          nodeNames.put(c, "c");
72          svgWriter.write(tree, nodeNames, new File(outputFolder, String.format(OUTPUT_FILE_FORMAT, ++cutCount)));
73  
74          tree.insert(Lines.segmentFromPoints(Vector2D.of(1, 0), Vector2D.of(-5, 3), precision));
75          tree.insert(Lines.segmentFromPoints(Vector2D.of(-5, 3), Vector2D.of(-5, 0), precision));
76  
77          RegionNode2D d = b.getMinus();
78          RegionNode2D e = b.getPlus();
79          RegionNode2D f = d.getMinus();
80          RegionNode2D g = d.getPlus();
81  
82          nodeNames.put(d, "d");
83          nodeNames.put(e, "e");
84          nodeNames.put(f, "f");
85          nodeNames.put(g, "g");
86          svgWriter.write(tree, nodeNames, new File(outputFolder, String.format(OUTPUT_FILE_FORMAT, ++cutCount)));
87  
88          LinePath path = LinePath.fromVertices(Arrays.asList(
89                  Vector2D.of(-1, 0),
90                  Vector2D.of(5, -3),
91                  Vector2D.of(5, 0),
92                  Vector2D.of(1, 0)), precision);
93          tree.insert(path);
94  
95          RegionNode2D h = c.getMinus();
96          RegionNode2D i = c.getPlus();
97          RegionNode2D j = h.getMinus();
98          RegionNode2D k = h.getPlus();
99  
100         nodeNames.put(h, "h");
101         nodeNames.put(i, "i");
102         nodeNames.put(j, "j");
103         nodeNames.put(k, "k");
104         svgWriter.write(tree, nodeNames, new File(outputFolder, String.format(OUTPUT_FILE_FORMAT, ++cutCount)));
105     }
106 }