1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.geometry.examples.tutorials.bsp;
18
19 import java.io.File;
20 import java.util.HashMap;
21 import java.util.Map;
22
23 import org.apache.commons.geometry.core.precision.DoublePrecisionContext;
24 import org.apache.commons.geometry.core.precision.EpsilonDoublePrecisionContext;
25 import org.apache.commons.geometry.euclidean.twod.Bounds2D;
26 import org.apache.commons.geometry.euclidean.twod.Line;
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.Vector2D;
31
32
33
34
35 public final class BottomUpBSPTreeConstruction {
36
37
38 private static final String OUTPUT_FILE_FORMAT = "bu-cut-%d.svg";
39
40
41 private BottomUpBSPTreeConstruction() {}
42
43
44
45
46
47 public static void main(String[] args) {
48 File outputFolder = new File(args.length > 0 ? args[0] : ".");
49 BSPTreeSVGWriter svgWriter = new BSPTreeSVGWriter(Bounds2D.from(Vector2D.of(-8, -8), Vector2D.of(8, 8)));
50
51 Map<RegionNode2D, String> nodeNames = new HashMap<>();
52 int cutCount = -1;
53
54
55 DoublePrecisionContext precision = new EpsilonDoublePrecisionContext(1e-6);
56
57
58 RegionBSPTree2D tree = RegionBSPTree2D.empty();
59
60 Line rootCut = Lines.fromPointAndDirection(Vector2D.ZERO, Vector2D.Unit.PLUS_X, precision);
61 RegionNode2D a = tree.getRoot();
62
63 nodeNames.put(a, "a");
64 svgWriter.write(tree, nodeNames, new File(outputFolder, String.format(OUTPUT_FILE_FORMAT, ++cutCount)));
65
66
67 a.cut(rootCut);
68
69 RegionNode2D b = a.getMinus();
70 RegionNode2D c = a.getPlus();
71
72 nodeNames.put(b, "b");
73 nodeNames.put(c, "c");
74 svgWriter.write(tree, nodeNames, new File(outputFolder, String.format(OUTPUT_FILE_FORMAT, ++cutCount)));
75
76
77 b.insertCut(Lines.fromPoints(Vector2D.of(1, 0), Vector2D.of(-1, 1), precision));
78
79 RegionNode2D d = b.getMinus();
80 RegionNode2D e = b.getPlus();
81
82 nodeNames.put(d, "d");
83 nodeNames.put(e, "e");
84 svgWriter.write(tree, nodeNames, new File(outputFolder, String.format(OUTPUT_FILE_FORMAT, ++cutCount)));
85
86 d.insertCut(Lines.fromPointAndDirection(Vector2D.of(-5, 1), Vector2D.Unit.MINUS_Y, precision));
87
88 RegionNode2D f = d.getMinus();
89 RegionNode2D g = d.getPlus();
90
91 nodeNames.put(f, "f");
92 nodeNames.put(g, "g");
93 svgWriter.write(tree, nodeNames, new File(outputFolder, String.format(OUTPUT_FILE_FORMAT, ++cutCount)));
94
95
96 c.insertCut(Lines.fromPoints(Vector2D.of(-1, 0), Vector2D.of(1, -1), precision));
97
98 RegionNode2D h = c.getMinus();
99 RegionNode2D i = c.getPlus();
100
101 nodeNames.put(h, "h");
102 nodeNames.put(i, "i");
103 svgWriter.write(tree, nodeNames, new File(outputFolder, String.format(OUTPUT_FILE_FORMAT, ++cutCount)));
104
105 h.insertCut(Lines.fromPointAndDirection(Vector2D.of(5, -1), Vector2D.Unit.PLUS_Y, precision));
106
107 RegionNode2D j = h.getMinus();
108 RegionNode2D k = h.getPlus();
109
110 nodeNames.put(j, "j");
111 nodeNames.put(k, "k");
112 svgWriter.write(tree, nodeNames, new File(outputFolder, String.format(OUTPUT_FILE_FORMAT, ++cutCount)));
113 }
114 }