View Javadoc

    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   */
    17  package org.apache.commons.geometry.core.partitioning;
    18
    19  import java.util.List;
    20
    21  import org.apache.commons.geometry.core.Point;
    22  import org.apache.commons.geometry.core.RegionLocation;
    23  import org.apache.commons.geometry.core.Sized;
    24  import org.apache.commons.geometry.core.Transform;
    25
    26  /** Interface representing a subset of the points lying in a hyperplane. Examples include
    27   * rays and line segments in Euclidean 2D space and triangular facets in Euclidean 3D space.
    28   * Hyperplane subsets can have finite or infinite size and can represent contiguous regions
    29   * of the hyperplane (as in the examples above); multiple, disjoint regions; or the
    30   * {@link Hyperplane#span() entire hyperplane}.
    31   *
    32   * <p>This interface is very similar to the {@link org.apache.commons.geometry.core.Region Region}
    33   * interface but has slightly different semantics. Whereas {@code Region} instances represent sets
    34   * of points that can expand through all of the dimensions of a space, {@code HyperplaneSubset} instances
    35   * are constrained to their containing hyperplane and are more accurately defined as {@code Region}s
    36   * of the {@code n-1} dimension subspace defined by the hyperplane. This makes the methods of this interface
    37   * have slightly different meanings as compared to their {@code Region} counterparts. For example, consider
    38   * a triangular facet in Euclidean 3D space. The {@link #getSize()} method of this hyperplane subset does
    39   * not return the <em>volume</em> of the instance (which would be {@code 0}) as a regular 3D region would, but
    40   * rather returns the <em>area</em> of the 2D polygon defined by the facet. Similarly, the {@link #classify(Point)}
    41   * method returns {@link RegionLocation#INSIDE} for points that lie inside of the 2D polygon defined by the
    42   * facet, instead of the {@link RegionLocation#BOUNDARY} value that would be expected if the facet was considered
    43   * as a true 3D region with zero thickness.
    44   * </p>
    45   *
    46   * @param <P> Point implementation type
    47   * @see Hyperplane
    48   */
    49  public interface HyperplaneSubset<P extends Point<P>> extends Splittable<P, HyperplaneSubset<P>>, Sized {
    50
    51      /** Get the hyperplane containing this instance.
    52       * @return the hyperplane containing this instance
    53       */
    54      Hyperplane<P> getHyperplane();
    55
    56      /** Return true if this instance contains all points in the
    57       * hyperplane.
    58       * @return true if this instance contains all points in the
    59       *      hyperplane
    60       */
    61      boolean isFull();
    62
    63      /** Return true if this instance does not contain any points.
    64       * @return true if this instance does not contain any points
    65       */
    66      boolean isEmpty();
    67
    68      /** Get the centroid, or geometric center, of the hyperplane subset or null
    69       * if no centroid exists or one exists but is not unique. A centroid will not
    70       * exist for empty or infinite subsets.
    71       *
    72       * <p>The centroid of a geometric object is defined as the mean position of
    73       * all points in the object, including interior points, vertices, and other points
    74       * lying on the boundary. If a physical object has a uniform density, then its center
    75       * of mass is the same as its geometric centroid.
    76       * </p>
    77       * @return the centroid of the hyperplane subset or null if no unique centroid exists
    78       * @see <a href="https://en.wikipedia.org/wiki/Centroid">Centroid</a>
    79       */
    80      P getCentroid();
    81
    82      /** Classify a point with respect to the subset region. The point is classified as follows:
    83       * <ul>
    84       *  <li>{@link RegionLocation#INSIDE INSIDE} - The point lies on the hyperplane
    85       *      and inside of the subset region.</li>
    86       *  <li>{@link RegionLocation#BOUNDARY BOUNDARY} - The point lies on the hyperplane
    87       *      and is on the boundary of the subset region.</li>
    88       *  <li>{@link RegionLocation#OUTSIDE OUTSIDE} - The point does not lie on
    89       *      the hyperplane or it does lie on the hyperplane but is outside of the
    90       *      subset region.</li>
    91       * </ul>
    92       * @param pt the point to classify
    93       * @return classification of the point with respect to the hyperplane
    94       *      and subspace region
    95       */
    96      RegionLocation classify(P pt);
    97
    98      /** Return true if the hyperplane subset contains the given point, meaning that the point
    99       * lies on the hyperplane and is not on the outside of the subset region.
    100      * @param pt the point to check
    101      * @return true if the point is contained in the hyperplane subset
    102      */
    103     default boolean contains(final P pt) {
    104         final RegionLocation loc = classify(pt);
    105         return loc != null && loc != RegionLocation.OUTSIDE;
    106     }
    107
    108     /** Return the closest point to the argument that is contained in the subset
    109      * (ie, not classified as {@link RegionLocation#OUTSIDE outside}), or null if no
    110      * such point exists.
    111      * @param pt the reference point
    112      * @return the closest point to the reference point that is contained in the subset,
    113      *      or null if no such point exists
    114      */
    115     P closest(P pt);
    116
    117     /** Return a new hyperplane subset resulting from the application of the given transform.
    118      * The current instance is not modified.
    119      * @param transform the transform instance to apply
    120      * @return new transformed hyperplane subset
    121      */
    122     HyperplaneSubset<P> transform(Transform<P> transform);
    123
    124     /** Convert this instance into a list of convex child subsets representing the same region.
    125      * Implementations are not required to return an optimal convex subdivision of the current
    126      * instance. They are free to return whatever subdivision is readily available.
    127      * @return a list of hyperplane convex subsets representing the same subspace
    128      *      region as this instance
    129      */
    130     List<? extends HyperplaneConvexSubset<P>> toConvex();
    131 }