org.apache.commons.math3.geometry.partitioning.InsideFinder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of commons-math3 Show documentation
Show all versions of commons-math3 Show documentation
The Apache Commons Math project is a library of lightweight, self-contained mathematics and statistics components addressing the most common practical problems not immediately available in the Java programming language or commons-lang.
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math3.geometry.partitioning;
import org.apache.commons.math3.geometry.Space;
/** Utility class checking if inside nodes can be found
* on the plus and minus sides of an hyperplane.
* @param Type of the space.
* @since 3.4
*/
class InsideFinder {
/** Region on which to operate. */
private final Region region;
/** Indicator of inside leaf nodes found on the plus side. */
private boolean plusFound;
/** Indicator of inside leaf nodes found on the plus side. */
private boolean minusFound;
/** Simple constructor.
* @param region region on which to operate
*/
InsideFinder(final Region region) {
this.region = region;
plusFound = false;
minusFound = false;
}
/** Search recursively for inside leaf nodes on each side of the given hyperplane.
* The algorithm used here is directly derived from the one
* described in section III (Binary Partitioning of a BSP
* Tree) of the Bruce Naylor, John Amanatides and William
* Thibault paper Merging
* BSP Trees Yields Polyhedral Set Operations Proc. Siggraph
* '90, Computer Graphics 24(4), August 1990, pp 115-124, published
* by the Association for Computing Machinery (ACM)..
* @param node current BSP tree node
* @param sub sub-hyperplane
*/
public void recurseSides(final BSPTree node, final SubHyperplane sub) {
if (node.getCut() == null) {
if ((Boolean) node.getAttribute()) {
// this is an inside cell expanding across the hyperplane
plusFound = true;
minusFound = true;
}
return;
}
final Hyperplane hyperplane = node.getCut().getHyperplane();
final SubHyperplane.SplitSubHyperplane split = sub.split(hyperplane);
switch (split.getSide()) {
case PLUS :
// the sub-hyperplane is entirely in the plus sub-tree
if (node.getCut().split(sub.getHyperplane()).getSide() == Side.PLUS) {
if (!region.isEmpty(node.getMinus())) {
plusFound = true;
}
} else {
if (!region.isEmpty(node.getMinus())) {
minusFound = true;
}
}
if (!(plusFound && minusFound)) {
recurseSides(node.getPlus(), sub);
}
break;
case MINUS :
// the sub-hyperplane is entirely in the minus sub-tree
if (node.getCut().split(sub.getHyperplane()).getSide() == Side.PLUS) {
if (!region.isEmpty(node.getPlus())) {
plusFound = true;
}
} else {
if (!region.isEmpty(node.getPlus())) {
minusFound = true;
}
}
if (!(plusFound && minusFound)) {
recurseSides(node.getMinus(), sub);
}
break;
case BOTH :
// the sub-hyperplane extends in both sub-trees
// explore first the plus sub-tree
recurseSides(node.getPlus(), split.getPlus());
// if needed, explore the minus sub-tree
if (!(plusFound && minusFound)) {
recurseSides(node.getMinus(), split.getMinus());
}
break;
default :
// the sub-hyperplane and the cut sub-hyperplane share the same hyperplane
if (node.getCut().getHyperplane().sameOrientationAs(sub.getHyperplane())) {
if ((node.getPlus().getCut() != null) || ((Boolean) node.getPlus().getAttribute())) {
plusFound = true;
}
if ((node.getMinus().getCut() != null) || ((Boolean) node.getMinus().getAttribute())) {
minusFound = true;
}
} else {
if ((node.getPlus().getCut() != null) || ((Boolean) node.getPlus().getAttribute())) {
minusFound = true;
}
if ((node.getMinus().getCut() != null) || ((Boolean) node.getMinus().getAttribute())) {
plusFound = true;
}
}
}
}
/** Check if inside leaf nodes have been found on the plus side.
* @return true if inside leaf nodes have been found on the plus side
*/
public boolean plusFound() {
return plusFound;
}
/** Check if inside leaf nodes have been found on the minus side.
* @return true if inside leaf nodes have been found on the minus side
*/
public boolean minusFound() {
return minusFound;
}
}