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 * https://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 18 /* 19 * This is not the original file distributed by the Apache Software Foundation 20 * It has been modified by the Hipparchus project 21 */ 22 package org.hipparchus.geometry.partitioning; 23 24 import org.hipparchus.geometry.Point; 25 import org.hipparchus.geometry.Space; 26 27 /** This interface represents a region of a space as a partition. 28 29 * <p>Region are subsets of a space, they can be infinite (whole 30 * space, half space, infinite stripe ...) or finite (polygons in 2D, 31 * polyhedrons in 3D ...). Their main characteristic is to separate 32 * points that are considered to be <em>inside</em> the region from 33 * points considered to be <em>outside</em> of it. In between, there 34 * may be points on the <em>boundary</em> of the region.</p> 35 36 * <p>This implementation is limited to regions for which the boundary 37 * is composed of several {@link SubHyperplane sub-hyperplanes}, 38 * including regions with no boundary at all: the whole space and the 39 * empty region. They are not necessarily finite and not necessarily 40 * path-connected. They can contain holes.</p> 41 42 * <p>Regions can be combined using the traditional sets operations : 43 * union, intersection, difference and symetric difference (exclusive 44 * or) for the binary operations, complement for the unary 45 * operation.</p> 46 47 * <p> 48 * Note that this interface is <em>not</em> intended to be implemented 49 * by Hipparchus users, it is only intended to be implemented 50 * within the library itself. New methods may be added even for minor 51 * versions, which breaks compatibility for external implementations. 52 * </p> 53 54 * @param <S> Type of the space. 55 56 */ 57 public interface Region<S extends Space> { 58 59 /** Enumerate for the location of a point with respect to the region. */ 60 enum Location { 61 /** Code for points inside the partition. */ 62 INSIDE, 63 64 /** Code for points outside of the partition. */ 65 OUTSIDE, 66 67 /** Code for points on the partition boundary. */ 68 BOUNDARY; 69 } 70 71 /** Build a region using the instance as a prototype. 72 * <p>This method allow to create new instances without knowing 73 * exactly the type of the region. It is an application of the 74 * prototype design pattern.</p> 75 * <p>The leaf nodes of the BSP tree <em>must</em> have a 76 * {@code Boolean} attribute representing the inside status of 77 * the corresponding cell (true for inside cells, false for outside 78 * cells). In order to avoid building too many small objects, it is 79 * recommended to use the predefined constants 80 * {@code Boolean.TRUE} and {@code Boolean.FALSE}. The 81 * tree also <em>must</em> have either null internal nodes or 82 * internal nodes representing the boundary as specified in the 83 * {@link #getTree getTree} method).</p> 84 * @param newTree inside/outside BSP tree representing the new region 85 * @return the built region 86 */ 87 Region<S> buildNew(BSPTree<S> newTree); 88 89 /** Copy the instance. 90 * <p>The instance created is completely independant of the original 91 * one. A deep copy is used, none of the underlying objects are 92 * shared (except for the underlying tree {@code Boolean} 93 * attributes and immutable objects).</p> 94 * @return a new region, copy of the instance 95 */ 96 Region<S> copySelf(); 97 98 /** Check if the instance is empty. 99 * @return true if the instance is empty 100 */ 101 boolean isEmpty(); 102 103 /** Check if the sub-tree starting at a given node is empty. 104 * @param node root node of the sub-tree (<em>must</em> have {@link 105 * Region Region} tree semantics, i.e. the leaf nodes must have 106 * {@code Boolean} attributes representing an inside/outside 107 * property) 108 * @return true if the sub-tree starting at the given node is empty 109 */ 110 boolean isEmpty(BSPTree<S> node); 111 112 /** Check if the instance covers the full space. 113 * @return true if the instance covers the full space 114 */ 115 boolean isFull(); 116 117 /** Check if the sub-tree starting at a given node covers the full space. 118 * @param node root node of the sub-tree (<em>must</em> have {@link 119 * Region Region} tree semantics, i.e. the leaf nodes must have 120 * {@code Boolean} attributes representing an inside/outside 121 * property) 122 * @return true if the sub-tree starting at the given node covers the full space 123 */ 124 boolean isFull(BSPTree<S> node); 125 126 /** Check if the instance entirely contains another region. 127 * @param region region to check against the instance 128 * @return true if the instance contains the specified tree 129 */ 130 boolean contains(Region<S> region); 131 132 /** Check a point with respect to the region. 133 * @param point point to check 134 * @return a code representing the point status: either {@link 135 * Location#INSIDE}, {@link Location#OUTSIDE} or {@link Location#BOUNDARY} 136 */ 137 Location checkPoint(Point<S> point); 138 139 /** Project a point on the boundary of the region. 140 * @param point point to check 141 * @return projection of the point on the boundary 142 */ 143 BoundaryProjection<S> projectToBoundary(Point<S> point); 144 145 /** Get the underlying BSP tree. 146 147 * <p>Regions are represented by an underlying inside/outside BSP 148 * tree whose leaf attributes are {@code Boolean} instances 149 * representing inside leaf cells if the attribute value is 150 * {@code true} and outside leaf cells if the attribute is 151 * {@code false}. These leaf attributes are always present and 152 * guaranteed to be non null.</p> 153 154 * <p>In addition to the leaf attributes, the internal nodes which 155 * correspond to cells split by cut sub-hyperplanes may contain 156 * {@link BoundaryAttribute BoundaryAttribute} objects representing 157 * the parts of the corresponding cut sub-hyperplane that belong to 158 * the boundary. When the boundary attributes have been computed, 159 * all internal nodes are guaranteed to have non-null 160 * attributes, however some {@link BoundaryAttribute 161 * BoundaryAttribute} instances may have their {@link 162 * BoundaryAttribute#getPlusInside() getPlusInside} and {@link 163 * BoundaryAttribute#getPlusOutside() getPlusOutside} methods both 164 * returning null if the corresponding cut sub-hyperplane does not 165 * have any parts belonging to the boundary.</p> 166 167 * <p>Since computing the boundary is not always required and can be 168 * time-consuming for large trees, these internal nodes attributes 169 * are computed using lazy evaluation only when required by setting 170 * the {@code includeBoundaryAttributes} argument to 171 * {@code true}. Once computed, these attributes remain in the 172 * tree, which implies that in this case, further calls to the 173 * method for the same region will always include these attributes 174 * regardless of the value of the 175 * {@code includeBoundaryAttributes} argument.</p> 176 177 * @param includeBoundaryAttributes if true, the boundary attributes 178 * at internal nodes are guaranteed to be included (they may be 179 * included even if the argument is false, if they have already been 180 * computed due to a previous call) 181 * @return underlying BSP tree 182 * @see BoundaryAttribute 183 */ 184 BSPTree<S> getTree(boolean includeBoundaryAttributes); 185 186 /** Get the size of the boundary. 187 * @return the size of the boundary (this is 0 in 1D, a length in 188 * 2D, an area in 3D ...) 189 */ 190 double getBoundarySize(); 191 192 /** Get the size of the instance. 193 * @return the size of the instance (this is a length in 1D, an area 194 * in 2D, a volume in 3D ...) 195 */ 196 double getSize(); 197 198 /** Get the barycenter of the instance. 199 * @return an object representing the barycenter 200 */ 201 Point<S> getBarycenter(); 202 203 /** Get the parts of a sub-hyperplane that are contained in the region. 204 * <p>The parts of the sub-hyperplane that belong to the boundary are 205 * <em>not</em> included in the resulting parts.</p> 206 * @param sub sub-hyperplane traversing the region 207 * @return filtered sub-hyperplane 208 */ 209 SubHyperplane<S> intersection(SubHyperplane<S> sub); 210 211 }