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.util.HashMap;
25 import java.util.Map;
26
27 import org.hipparchus.geometry.Point;
28 import org.hipparchus.geometry.Space;
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 public abstract class AbstractSubHyperplane<S extends Space,
50 P extends Point<S, P>,
51 H extends Hyperplane<S, P, H, I>,
52 I extends SubHyperplane<S, P, H, I>,
53 T extends Space, Q extends Point<T, Q>,
54 F extends Hyperplane<T, Q, F, J>,
55 J extends SubHyperplane<T, Q, F, J>>
56 implements SubHyperplane<S, P, H, I> {
57
58
59 private final H hyperplane;
60
61
62 private final Region<T, Q, F, J> remainingRegion;
63
64
65
66
67
68 protected AbstractSubHyperplane(final H hyperplane,
69 final Region<T, Q, F, J> remainingRegion) {
70 this.hyperplane = hyperplane;
71 this.remainingRegion = remainingRegion;
72 }
73
74
75
76
77
78
79 protected abstract I buildNew(H hyper, Region<T, Q, F, J> remaining);
80
81
82 @Override
83 public I copySelf() {
84 return buildNew(hyperplane.copySelf(), remainingRegion);
85 }
86
87
88
89
90 @Override
91 public H getHyperplane() {
92 return hyperplane;
93 }
94
95
96
97
98
99
100
101
102 public Region<T, Q, F, J> getRemainingRegion() {
103 return remainingRegion;
104 }
105
106
107 @Override
108 public double getSize() {
109 return remainingRegion.getSize();
110 }
111
112
113 @Override
114 public I reunite(final I other) {
115 @SuppressWarnings("unchecked")
116 AbstractSubHyperplane<S, P, H, I, T, Q, F, J> o = (AbstractSubHyperplane<S, P, H, I, T, Q, F, J>) other;
117 return buildNew(hyperplane,
118 new RegionFactory<T, Q, F, J>().union(remainingRegion, o.remainingRegion));
119 }
120
121
122
123
124
125
126
127
128
129
130
131 public I applyTransform(final Transform<S, P, H, I, T, Q, F, J> transform) {
132 final H tHyperplane = transform.apply(hyperplane);
133
134
135 final Map<BSPTree<T, Q, F, J>, BSPTree<T, Q, F, J>> map = new HashMap<>();
136 final BSPTree<T, Q, F, J> tTree =
137 recurseTransform(remainingRegion.getTree(false), tHyperplane, transform, map);
138
139
140 for (final Map.Entry<BSPTree<T, Q, F, J>, BSPTree<T, Q, F, J>> entry : map.entrySet()) {
141 if (entry.getKey().getCut() != null) {
142 @SuppressWarnings("unchecked")
143 BoundaryAttribute<T, Q, F, J> original = (BoundaryAttribute<T, Q, F, J>) entry.getKey().getAttribute();
144 if (original != null) {
145 @SuppressWarnings("unchecked")
146 BoundaryAttribute<T, Q, F, J> transformed = (BoundaryAttribute<T, Q, F, J>) entry.getValue().getAttribute();
147 for (final BSPTree<T, Q, F, J> splitter : original.getSplitters()) {
148 transformed.getSplitters().add(map.get(splitter));
149 }
150 }
151 }
152 }
153
154 return buildNew(tHyperplane, remainingRegion.buildNew(tTree));
155
156 }
157
158
159
160
161
162
163
164
165 private BSPTree<T, Q, F, J> recurseTransform(final BSPTree<T, Q, F, J> node,
166 final H transformed,
167 final Transform<S, P, H, I, T, Q, F, J> transform,
168 final Map<BSPTree<T, Q, F, J>, BSPTree<T, Q, F, J>> map) {
169
170 final BSPTree<T, Q, F, J> transformedNode;
171 if (node.getCut() == null) {
172 transformedNode = new BSPTree<>(node.getAttribute());
173 } else {
174
175 @SuppressWarnings("unchecked")
176 BoundaryAttribute<T, Q, F, J> attribute = (BoundaryAttribute<T, Q, F, J>) node.getAttribute();
177 if (attribute != null) {
178 final J tPO = (attribute.getPlusOutside() == null) ?
179 null : transform.apply(attribute.getPlusOutside(), hyperplane, transformed);
180 final J tPI = (attribute.getPlusInside() == null) ?
181 null : transform.apply(attribute.getPlusInside(), hyperplane, transformed);
182
183 attribute = new BoundaryAttribute<>(tPO, tPI, new NodesSet<>());
184 }
185
186 transformedNode = new BSPTree<>(transform.apply(node.getCut(), hyperplane, transformed),
187 recurseTransform(node.getPlus(), transformed, transform, map),
188 recurseTransform(node.getMinus(), transformed, transform, map),
189 attribute);
190 }
191
192 map.put(node, transformedNode);
193 return transformedNode;
194
195 }
196
197
198 @Override
199 public abstract SplitSubHyperplane<S, P, H, I> split(H hyper);
200
201
202 @Override
203 public boolean isEmpty() {
204 return remainingRegion.isEmpty();
205 }
206
207 }