source: src/main/java/agents/anac/y2019/harddealer/math3/geometry/partitioning/Characterization.java

Last change on this file was 204, checked in by Katsuhide Fujita, 5 years ago

Fixed errors of ANAC2019 agents

  • Property svn:executable set to *
File size: 7.5 KB
Line 
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 */
17package agents.anac.y2019.harddealer.math3.geometry.partitioning;
18
19import java.util.ArrayList;
20import java.util.List;
21
22import agents.anac.y2019.harddealer.math3.exception.MathInternalError;
23import agents.anac.y2019.harddealer.math3.geometry.Space;
24
25/** Cut sub-hyperplanes characterization with respect to inside/outside cells.
26 * @see BoundaryBuilder
27 * @param <S> Type of the space.
28 * @since 3.4
29 */
30class Characterization<S extends Space> {
31
32 /** Part of the cut sub-hyperplane that touch outside cells. */
33 private SubHyperplane<S> outsideTouching;
34
35 /** Part of the cut sub-hyperplane that touch inside cells. */
36 private SubHyperplane<S> insideTouching;
37
38 /** Nodes that were used to split the outside touching part. */
39 private final NodesSet<S> outsideSplitters;
40
41 /** Nodes that were used to split the outside touching part. */
42 private final NodesSet<S> insideSplitters;
43
44 /** Simple constructor.
45 * <p>Characterization consists in splitting the specified
46 * sub-hyperplane into several parts lying in inside and outside
47 * cells of the tree. The principle is to compute characterization
48 * twice for each cut sub-hyperplane in the tree, once on the plus
49 * node and once on the minus node. The parts that have the same flag
50 * (inside/inside or outside/outside) do not belong to the boundary
51 * while parts that have different flags (inside/outside or
52 * outside/inside) do belong to the boundary.</p>
53 * @param node current BSP tree node
54 * @param sub sub-hyperplane to characterize
55 */
56 Characterization(final BSPTree<S> node, final SubHyperplane<S> sub) {
57 outsideTouching = null;
58 insideTouching = null;
59 outsideSplitters = new NodesSet<S>();
60 insideSplitters = new NodesSet<S>();
61 characterize(node, sub, new ArrayList<BSPTree<S>>());
62 }
63
64 /** Filter the parts of an hyperplane belonging to the boundary.
65 * <p>The filtering consist in splitting the specified
66 * sub-hyperplane into several parts lying in inside and outside
67 * cells of the tree. The principle is to call this method twice for
68 * each cut sub-hyperplane in the tree, once on the plus node and
69 * once on the minus node. The parts that have the same flag
70 * (inside/inside or outside/outside) do not belong to the boundary
71 * while parts that have different flags (inside/outside or
72 * outside/inside) do belong to the boundary.</p>
73 * @param node current BSP tree node
74 * @param sub sub-hyperplane to characterize
75 * @param splitters nodes that did split the current one
76 */
77 private void characterize(final BSPTree<S> node, final SubHyperplane<S> sub,
78 final List<BSPTree<S>> splitters) {
79 if (node.getCut() == null) {
80 // we have reached a leaf node
81 final boolean inside = (Boolean) node.getAttribute();
82 if (inside) {
83 addInsideTouching(sub, splitters);
84 } else {
85 addOutsideTouching(sub, splitters);
86 }
87 } else {
88 final Hyperplane<S> hyperplane = node.getCut().getHyperplane();
89 final SubHyperplane.SplitSubHyperplane<S> split = sub.split(hyperplane);
90 switch (split.getSide()) {
91 case PLUS:
92 characterize(node.getPlus(), sub, splitters);
93 break;
94 case MINUS:
95 characterize(node.getMinus(), sub, splitters);
96 break;
97 case BOTH:
98 splitters.add(node);
99 characterize(node.getPlus(), split.getPlus(), splitters);
100 characterize(node.getMinus(), split.getMinus(), splitters);
101 splitters.remove(splitters.size() - 1);
102 break;
103 default:
104 // this should not happen
105 throw new MathInternalError();
106 }
107 }
108 }
109
110 /** Add a part of the cut sub-hyperplane known to touch an outside cell.
111 * @param sub part of the cut sub-hyperplane known to touch an outside cell
112 * @param splitters sub-hyperplanes that did split the current one
113 */
114 private void addOutsideTouching(final SubHyperplane<S> sub,
115 final List<BSPTree<S>> splitters) {
116 if (outsideTouching == null) {
117 outsideTouching = sub;
118 } else {
119 outsideTouching = outsideTouching.reunite(sub);
120 }
121 outsideSplitters.addAll(splitters);
122 }
123
124 /** Add a part of the cut sub-hyperplane known to touch an inside cell.
125 * @param sub part of the cut sub-hyperplane known to touch an inside cell
126 * @param splitters sub-hyperplanes that did split the current one
127 */
128 private void addInsideTouching(final SubHyperplane<S> sub,
129 final List<BSPTree<S>> splitters) {
130 if (insideTouching == null) {
131 insideTouching = sub;
132 } else {
133 insideTouching = insideTouching.reunite(sub);
134 }
135 insideSplitters.addAll(splitters);
136 }
137
138 /** Check if the cut sub-hyperplane touches outside cells.
139 * @return true if the cut sub-hyperplane touches outside cells
140 */
141 public boolean touchOutside() {
142 return outsideTouching != null && !outsideTouching.isEmpty();
143 }
144
145 /** Get all the parts of the cut sub-hyperplane known to touch outside cells.
146 * @return parts of the cut sub-hyperplane known to touch outside cells
147 * (may be null or empty)
148 */
149 public SubHyperplane<S> outsideTouching() {
150 return outsideTouching;
151 }
152
153 /** Get the nodes that were used to split the outside touching part.
154 * <p>
155 * Splitting nodes are internal nodes (i.e. they have a non-null
156 * cut sub-hyperplane).
157 * </p>
158 * @return nodes that were used to split the outside touching part
159 */
160 public NodesSet<S> getOutsideSplitters() {
161 return outsideSplitters;
162 }
163
164 /** Check if the cut sub-hyperplane touches inside cells.
165 * @return true if the cut sub-hyperplane touches inside cells
166 */
167 public boolean touchInside() {
168 return insideTouching != null && !insideTouching.isEmpty();
169 }
170
171 /** Get all the parts of the cut sub-hyperplane known to touch inside cells.
172 * @return parts of the cut sub-hyperplane known to touch inside cells
173 * (may be null or empty)
174 */
175 public SubHyperplane<S> insideTouching() {
176 return insideTouching;
177 }
178
179 /** Get the nodes that were used to split the inside touching part.
180 * <p>
181 * Splitting nodes are internal nodes (i.e. they have a non-null
182 * cut sub-hyperplane).
183 * </p>
184 * @return nodes that were used to split the inside touching part
185 */
186 public NodesSet<S> getInsideSplitters() {
187 return insideSplitters;
188 }
189
190}
Note: See TracBrowser for help on using the repository browser.